# FreeBSD Manual Pages

BC(1) General Commands Manual BC(1)NAMEbc - arbitrary-precision decimal arithmetic language and calculatorSYNOPSISbc[-ghilPqRsvVw] [--global-stacks] [--help] [--interactive] [--math-lib] [--no-prompt] [--no-read-prompt] [--quiet] [--standard] [--warn] [--version] [-eexpr] [--expression=expr...] [-ffile...] [--file=file...] [file...]DESCRIPTIONbc(1) is an interactive processor for a language first standardized in 1991 by POSIX. (The current standard is here (https://pubs.open- group.org/onlinepubs/9699919799/utilities/bc.html).) The language pro- vides unlimited precision decimal arithmetic and is somewhat C-like, but there are differences. Such differences will be noted in this doc- ument. After parsing and handling options, this bc(1) reads any files given on the command line and executes them before reading fromstdin. This bc(1) is a drop-in replacement foranybc(1), including (and espe- cially) the GNU bc(1). It also has many extensions and extra features beyond other implementations.Note: If running this bc(1) onanyscript meant for another bc(1) gives a parse error, it is probably because a word this bc(1) reserves as a keyword is used as the name of a function, variable, or array. To fix that, use the command-line option-rkeyword, wherekeywordis the key- word that is used as a name in the script. For more information, see theOPTIONSsection. If parsing scripts meant for other bc(1) implementations still does not work, that is a bug and should be reported. See theBUGSsection.OPTIONSThe following are the options that bc(1) accepts.-g,--global-stacksTurns the globalsibase,obase,scale, andseedinto stacks. This has the effect that a copy of the current value of all four are pushed onto a stack for every function call, as well as popped when every function returns. This means that functions can assign to any and all of those globals without worrying that the change will affect other functions. Thus, a hypothetical function namedoutput(x,b)that simply printedxin basebcould be written like this: define void output(x, b) { obase=b x } instead of like this: define void output(x, b) { auto c c=obase obase=b x obase=c } This makes writing functions much easier. (Note: the functionoutput(x,b)exists in the extended math li- brary. See theLIBRARYsection.) However, since using this flag means that functions cannot setibase,obase,scale, orseedglobally, functions that are made to do so cannot work anymore. There are two possible use cases for that, and each has a solution. First, if a function is called on startup to turn bc(1) into a number converter, it is possible to replace that capability with various shell aliases. Examples: alias d2o="bc -e ibase=A -e obase=8" alias h2b="bc -e ibase=G -e obase=2" Second, if the purpose of a function is to setibase,obase,scale, orseedglobally for any other purpose, it could be split into one to four functions (based on how many globals it sets) and each of those functions could return the desired value for a global. For functions that setseed, the value assigned toseedis not propagated to parent functions. This means that the sequence of pseudo-random numbers that they see will not be the same se- quence of pseudo-random numbers that any parent sees. This is only the case onceseedhas been set. If a function desires to not affect the sequence of pseudo-ran- dom numbers of its parents, but wants to use the sameseed, it can use the following line: seed = seed If the behavior of this option is desired for every run of bc(1), then users could make sure to defineBC_ENV_ARGSand in- clude this option (see theENVIRONMENTVARIABLESsection for more details). If-s,-w, or any equivalents are used, this option is ignored. This is anon-portableextension.-h,--helpPrints a usage message and quits.-i,--interactiveForces interactive mode. (See theINTERACTIVEMODEsection.) This is anon-portableextension.-L,--no-line-lengthDisables line length checking and prints numbers without back- slashes and newlines. In other words, this option setsBC_LINE_LENGTHto0(see theENVIRONMENTVARIABLESsection). This is anon-portableextension.-l,--mathlibSetsscale(see theSYNTAXsection) to20and loads the included math library and the extended math library before running any code, including any expressions or files specified on the com- mand line. To learn what is in the libraries, see theLIBRARYsection.-P,--no-promptDisables the prompt in TTY mode. (The prompt is only enabled in TTY mode. See theTTYMODEsection.) This is mostly for those users that do not want a prompt or are not used to having them in bc(1). Most of those users would want to put this option inBC_ENV_ARGS(see theENVIRONMENTVARIABLESsection). These options override theBC_PROMPTandBC_TTY_MODEenvironment variables (see theENVIRONMENTVARIABLESsection). This is anon-portableextension.-R,--no-read-promptDisables the read prompt in TTY mode. (The read prompt is only enabled in TTY mode. See theTTYMODEsection.) This is mostly for those users that do not want a read prompt or are not used to having them in bc(1). Most of those users would want to put this option inBC_ENV_ARGS(see theENVIRONMENTVARIABLESsec- tion). This option is also useful in hash bang lines of bc(1) scripts that prompt for user input. This option does not disable the regular prompt because the read prompt is only used when theread()built-in function is called. These optionsdooverride theBC_PROMPTandBC_TTY_MODEenviron- ment variables (see theENVIRONMENTVARIABLESsection), but only for the read prompt. This is anon-portableextension.-rkeyword,--redefine=keywordRedefineskeywordin order to allow it to be used as a function, variable, or array name. This is useful when this bc(1) gives parse errors when parsing scripts meant for other bc(1) imple- mentations. The keywords this bc(1) allows to be redefined are:oabsoasciifyocontinueodivmodoelseohaltoirandolastolimitsomaxibaseomaxobaseomaxrandomaxscaleomodexpoorandoreadoseedostreamIf any of those keywords are used as a function, variable, or array name in a script, use this option with the keyword as the argument. If multiple are used, use this option for all of them; it can be used multiple times. Keywords arenotredefined when parsing the builtin math library (see theLIBRARYsection). It is a fatal error to redefine keywords mandated by the POSIX standard. It is a fatal error to attempt to redefine words that this bc(1) does not reserve as keywords.-q,--quietThis option is for compatibility with the GNU bc(1) (https://www.gnu.org/software/bc/); it is a no-op. Without this option, GNU bc(1) prints a copyright header. This bc(1) only prints the copyright header if one or more of the-v,-V, or--versionoptions are given. This is anon-portableextension.-s,--standardProcess exactly the language defined by the standard (https://pubs.opengroup.org/onlinepubs/9699919799/utili- ties/bc.html) and error if any extensions are used. This is anon-portableextension.-v,-V,--versionPrint the version information (copyright header) and exit. This is anon-portableextension.-w,--warnLike-sand--standard, except that warnings (and not errors) are printed for non-standard extensions and execution continues normally. This is anon-portableextension.-z,--leading-zeroesMakes bc(1) print all numbers greater than-1and less than1, and not equal to0, with a leading zero. This can be set for individual numbers with theplz(x), plznl(x)**,pnlz(x), andpnlznl(x)functions in the extended math library (see theLIBRARYsection). This is anon-portableextension.-eexpr,--expression=exprEvaluatesexpr. If multiple expressions are given, they are evaluated in order. If files are given as well (see below), the expressions and files are evaluated in the order given. This means that if a file is given before an expression, the file is read in and evaluated first. If this option is given on the command-line (i.e., not inBC_ENV_ARGS, see theENVIRONMENTVARIABLESsection), then after processing all expressions and files, bc(1) will exit, unless-(stdin) was given as an argument at least once to-for--file, whether on the command-line or inBC_ENV_ARGS. However, if any other-e,--expression,-f, or--filearguments are given after-f-or equivalent is given, bc(1) will give a fatal error and exit. This is anon-portableextension.-ffile,--file=fileReads infileand evaluates it, line by line, as though it were read throughstdin. If expressions are also given (see above), the expressions are evaluated in the order given. If this option is given on the command-line (i.e., not inBC_ENV_ARGS, see theENVIRONMENTVARIABLESsection), then after processing all expressions and files, bc(1) will exit, unless-(stdin) was given as an argument at least once to-for--file. However, if any other-e,--expression,-f, or--filearguments are given after-f-or equivalent is given, bc(1) will give a fatal error and exit. This is anon-portableextension. All long options arenon-portableextensions.STDINIf no files or expressions are given by the-f,--file,-e, or--ex-pressionoptions, then bc(1) read fromstdin. However, there are a few caveats to this. First,stdinis evaluated a line at a time. The only exception to this is if the parse cannot complete. That means that starting a string without ending it or starting a function,ifstatement, or loop without ending it will also cause bc(1) to not execute. Second, after anifstatement, bc(1) doesn't know if anelsestatement will follow, so it will not execute until it knows there will not be anelsestatement.STDOUTAny non-error output is written tostdout. In addition, if history (see theHISTORYsection) and the prompt (see theTTYMODEsection) are enabled, both are output tostdout.Note: Unlike other bc(1) implementations, this bc(1) will issue a fatal error (see theEXITSTATUSsection) if it cannot write tostdout, so ifstdoutis closed, as inbc>&-, it will quit with an error. This is done so that bc(1) can report problems whenstdoutis redirected to a file. If there are scripts that depend on the behavior of other bc(1) imple- mentations, it is recommended that those scripts be changed to redirectstdoutto/dev/null.STDERRAny error output is written tostderr.Note: Unlike other bc(1) implementations, this bc(1) will issue a fatal error (see theEXITSTATUSsection) if it cannot write tostderr, so ifstderris closed, as inbc2>&-, it will quit with an error. This is done so that bc(1) can exit with an error code whenstderris redi- rected to a file. If there are scripts that depend on the behavior of other bc(1) imple- mentations, it is recommended that those scripts be changed to redirectstderrto/dev/null.SYNTAXThe syntax for bc(1) programs is mostly C-like, with some differences. This bc(1) follows the POSIX standard (https://pubs.opengroup.org/on- linepubs/9699919799/utilities/bc.html), which is a much more thorough resource for the language this bc(1) accepts. This section is meant to be a summary and a listing of all the extensions to the standard. In the sections below,Emeans expression,Smeans statement, andImeans identifier. Identifiers (I) start with a lowercase letter and can be followed by any number (up toBC_NAME_MAX-1) of lowercase letters (a-z), digits (0-9), and underscores (_). The regex is[a-z][a-z0-9_]*. Identifiers with more than one character (letter) are anon-portableextension.ibaseis a global variable determining how to interpret constant num- bers. It is the "input" base, or the number base used for interpreting input numbers.ibaseis initially10. If the-s(--standard) and-w(--warn) flags were not given on the command line, the max allowable value foribaseis36. Otherwise, it is16. The min allowable value foribaseis2. The max allowable value foribasecan be queried in bc(1) programs with themaxibase()built-in function.obaseis a global variable determining how to output results. It is the "output" base, or the number base used for outputting numbers.obaseis initially10. The max allowable value forobaseisBC_BASE_MAXand can be queried in bc(1) programs with themaxobase()built-in function. The min allowable value forobaseis0. Ifobaseis0, values are output in scientific notation, and ifobaseis1, val- ues are output in engineering notation. Otherwise, values are output in the specified base. Outputting in scientific and engineering notations arenon-portableex-tensions. Thescaleof an expression is the number of digits in the result of the expression right of the decimal point, andscaleis a global variable that sets the precision of any operations, with exceptions.scaleis initially0.scalecannot be negative. The max allowable value forscaleisBC_SCALE_MAXand can be queried in bc(1) programs with themaxscale()built-in function. bc(1) has bothglobalvariables andlocalvariables. Alllocalvari- ables are local to the function; they are parameters or are introduced in theautolist of a function (see theFUNCTIONSsection). If a vari- able is accessed which is not a parameter or in theautolist, it is assumed to beglobal. If a parent function has alocalvariable ver- sion of a variable that a child function considersglobal, the value of thatglobalvariable in the child function is the value of the variable in the parent function, not the value of the actualglobalvariable. All of the above applies to arrays as well. The value of a statement that is an expression (i.e., any of the named expressions or operands) is printed unless the lowest precedence opera- tor is an assignment operatorandthe expression is notsurrounded by parentheses. The value that is printed is also assigned to the special variablelast. A single dot (.) may also be used as a synonym forlast. These arenon-portableextensions. Either semicolons or newlines may separate statements.CommentsThere are two kinds of comments: 1. Block comments are enclosed in/*and*/. 2. Line comments go from#until, and not including, the next newline. This is anon-portableextension.NamedExpressionsThe following are named expressions in bc(1): 1. Variables:I2. Array Elements:I[E]3.ibase4.obase5.scale6.seed7.lastor a single dot (.) Numbers 6 and 7 arenon-portableextensions. The meaning ofseedis dependent on the current pseudo-random number generator but is guaranteed to not change except for new major ver- sions. Thescaleand sign of the value may be significant. If a previously usedseedvalue is assigned toseedand used again, the pseudo-random number generator is guaranteed to produce the same se- quence of pseudo-random numbers as it did when theseedvalue was pre- viously used. The exact value assigned toseedis not guaranteed to be returned ifseedis queried again immediately. However, ifseeddoesreturn a dif- ferent value, both values, when assigned toseed, are guaranteed to produce the same sequence of pseudo-random numbers. This means that certain values assigned toseedwillnotproduce unique sequences of pseudo-random numbers. The value ofseedwill change after any use of therand()andirand(E)operands (see theOperandssubsection below), except if the parameter passed toirand(E)is0,1, or negative. There is no limit to the length (number of significant decimal digits) orscaleof the value that can be assigned toseed. Variables and arrays do not interfere; users can have arrays named the same as variables. This also applies to functions (see theFUNCTIONSsection), so a user can have a variable, array, and function that all have the same name, and they will not shadow each other, whether inside of functions or not. Named expressions are required as the operand ofincrement/decrementoperators and as the left side ofassignmentoperators (see theOpera-torssubsection).OperandsThe following are valid operands in bc(1): 1. Numbers (see theNumberssubsection below). 2. Array indices (I[E]). 3.(E): The value ofE(used to change precedence). 4.sqrt(E): The square root ofE.Emust be non-negative. 5.length(E): The number of significant decimal digits inE. Returns1for0with no decimal places. If given a string, the length of the string is returned. Passing a string tolength(E)is anon-portableextension. 6.length(I[]): The number of elements in the arrayI. This is anon-portableextension. 7.scale(E): ThescaleofE. 8.abs(E): The absolute value ofE. This is anon-portableextension. 9.modexp(E,E,E): Modular exponentiation, where the first expression is the base, the second is the exponent, and the third is the modu- lus. All three values must be integers. The second argument must be non-negative. The third argument must be non-zero. This is anon-portableextension. 10.divmod(E,E,I[]): Division and modulus in one operation. This is for optimization. The first expression is the dividend, and the second is the divisor, which must be non-zero. The return value is the quotient, and the modulus is stored in index0of the provided array (the last argument). This is anon-portableextension. 11.asciify(E): IfEis a string, returns a string that is the first letter of its argument. If it is a number, calculates the number mod256and returns that number as a one-character string. This is anon-portableextension. 12.I(),I(E),I(E,E), and so on, whereIis an identifier for a non-voidfunction (see theVoidFunctionssubsection of theFUNCTIONSsection). TheEargument(s) may also be arrays of the formI[], which will automatically be turned into array references (see theArrayReferencessubsection of theFUNCTIONSsection) if the corre- sponding parameter in the function definition is an array refer- ence. 13.read(): Reads a line fromstdinand uses that as an expression. The result of that expression is the result of theread()operand. This is anon-portableextension. 14.maxibase(): The max allowableibase. This is anon-portableexten-sion. 15.maxobase(): The max allowableobase. This is anon-portableexten-sion. 16.maxscale(): The max allowablescale. This is anon-portableexten-sion. 17.line_length(): The line length set withBC_LINE_LENGTH(see theEN-VIRONMENTVARIABLESsection). This is anon-portableextension. 18.global_stacks():0if global stacks are not enabled with the-gor--global-stacksoptions, non-zero otherwise. See theOPTIONSsec- tion. This is anon-portableextension. 19.leading_zero():0if leading zeroes are not enabled with the-zor-leading-zeroesoptions, non-zero otherwise. See theOPTIONSsec- tion. This is anon-portableextension. 20.rand(): A pseudo-random integer between0(inclusive) andBC_RAND_MAX(inclusive). Using this operand will change the value ofseed. This is anon-portableextension. 21.irand(E): A pseudo-random integer between0(inclusive) and the value ofE(exclusive). IfEis negative or is a non-integer (E'sscaleis not0), an error is raised, and bc(1) resets (see theRE-SETsection) whileseedremains unchanged. IfEis larger thanBC_RAND_MAX, the higher bound is honored by generating several pseudo-random integers, multiplying them by appropriate powers ofBC_RAND_MAX+1, and adding them together. Thus, the size of integer that can be generated with this operand is unbounded. Using this operand will change the value ofseed, unless the value ofEis0or1. In that case,0is returned, andseedisnotchanged. This is anon-portableextension. 22.maxrand(): The max integer returned byrand(). This is anon-por-tableextension. The integers generated byrand()andirand(E)are guaranteed to be as unbiased as possible, subject to the limitations of the pseudo-random number generator.Note: The values returned by the pseudo-random number generator withrand()andirand(E)are guaranteed toNOTbe cryptographically secure. This is a consequence of using a seeded pseudo-random number generator. However, theyareguaranteed to be reproducible with identicalseedvalues. This means that the pseudo-random values from bc(1) should only be used where a reproducible stream of pseudo-random numbers isESSENTIAL. In any other case, use a non-seeded pseudo-random number generator.NumbersNumbers are strings made up of digits, uppercase letters, and at most1period for a radix. Numbers can have up toBC_NUM_MAXdigits. Upper- case letters are equal to9+ their position in the alphabet (i.e.,Aequals10, or9+1). If a digit or letter makes no sense with the cur- rent value ofibase, they are set to the value of the highest valid digit inibase. Single-character numbers (i.e.,Aalone) take the value that they would have if they were valid digits, regardless of the value ofibase. This means thatAalone always equals decimal10andZalone always equals decimal35. In addition, bc(1) accepts numbers in scientific notation. These have the form <number>e<integer>. The exponent (the portion after thee) must be an integer. An example is1.89237e9, which is equal to1892370000. Negative exponents are also allowed, so4.2890e-3is equal to0.0042890. Using scientific notation is an error or warning if the-sor-w, re- spectively, command-line options (or equivalents) are given.WARNING: Both the number and the exponent in scientific notation are interpreted according to the currentibase, but the number is still multiplied by10^exponentregardless of the currentibase. For exam- ple, ifibaseis16and bc(1) is given the number stringFFeA, the re- sulting decimal number will be2550000000000, and if bc(1) is given the number string10e-4, the resulting decimal number will be0.0016. Accepting input as scientific notation is anon-portableextension.OperatorsThe following arithmetic and logical operators can be used. They are listed in order of decreasing precedence. Operators in the same group have the same precedence.++--Type: Prefix and Postfix Associativity: None Description:increment,decrement-!Type: Prefix Associativity: None Description:negation,booleannot$Type: Postfix Associativity: None Description:truncation@Type: Binary Associativity: Right Description:setprecision^Type: Binary Associativity: Right Description:power*/%Type: Binary Associativity: Left Description:multiply,divide,modulus+-Type: Binary Associativity: Left Description:add,subtract<< >> Type: Binary Associativity: Left Description:shiftleft,shiftright=<<=>>=+=-=*=/=%=^=@=Type: Binary Associativity: Right Description:assignment==<=>=!=< > Type: Binary Associativity: Left Description:relational&& Type: Binary Associativity: Left Description:booleanand||Type: Binary Associativity: Left Description:booleanorThe operators will be described in more detail below.++--The prefix and postfixincrementanddecrementoperators behave exactly like they would in C. They require a named expression (see theNamedExpressionssubsection) as an operand. The prefix versions of these operators are more efficient; use them where possible.-Thenegationoperator returns0if a user attempts to negate any expression with the value0. Otherwise, a copy of the expres- sion with its sign flipped is returned.!Thebooleannotoperator returns1if the expression is0, or0otherwise. This is anon-portableextension.$Thetruncationoperator returns a copy of the given expression with all of itsscaleremoved. This is anon-portableextension.@Thesetprecisionoperator takes two expressions and returns a copy of the first with itsscaleequal to the value of the sec- ond expression. That could either mean that the number is re- turned without change (if thescaleof the first expression matches the value of the second expression), extended (if it is less), or truncated (if it is more). The second expression must be an integer (noscale) and non-neg- ative. This is anon-portableextension.^Thepoweroperator (not theexclusiveoroperator, as it would be in C) takes two expressions and raises the first to the power of the value of the second. Thescaleof the result is equal toscale. The second expression must be an integer (noscale), and if it is negative, the first value must be non-zero.*Themultiplyoperator takes two expressions, multiplies them, and returns the product. Ifais thescaleof the first expres- sion andbis thescaleof the second expression, thescaleof the result is equal tomin(a+b,max(scale,a,b))wheremin()andmax()return the obvious values./Thedivideoperator takes two expressions, divides them, and re- turns the quotient. Thescaleof the result shall be the value ofscale. The second expression must be non-zero.%Themodulusoperator takes two expressions,aandb, and evalu- ates them by 1) Computinga/bto currentscaleand 2) Using the result of step 1 to calculatea-(a/b)*btoscalemax(scale+scale(b),scale(a)). The second expression must be non-zero.+Theaddoperator takes two expressions,aandb, and returns the sum, with ascaleequal to the max of thescales ofaandb.-Thesubtractoperator takes two expressions,aandb, and re- turns the difference, with ascaleequal to the max of thescales ofaandb. << Theleftshiftoperator takes two expressions,aandb, and re- turns a copy of the value ofawith its decimal point movedbplaces to the right. The second expression must be an integer (noscale) and non-neg- ative. This is anon-portableextension. >> Therightshiftoperator takes two expressions,aandb, and re- turns a copy of the value ofawith its decimal point movedbplaces to the left. The second expression must be an integer (noscale) and non-neg- ative. This is anon-portableextension.=<<=>>=+=-=*=/=%=^=@=Theassignmentoperators take two expressions,aandbwhereais a named expression (see theNamedExpressionssubsection). For=,bis copied and the result is assigned toa. For all others,aandbare applied as operands to the corresponding arithmetic operator and the result is assigned toa. Theassignmentoperators that correspond to operators that are extensions are themselvesnon-portableextensions.==<=>=!=< > Therelationaloperators compare two expressions,aandb, and if the relation holds, according to C language semantics, the result is1. Otherwise, it is0. Note that unlike in C, these operators have a lower precedence than theassignmentoperators, which means thata=b>cis inter- preted as(a=b)>c. Also, unlike the standard (https://pubs.opengroup.org/on- linepubs/9699919799/utilities/bc.html) requires, these operators can appear anywhere any other expressions can be used. This al- lowance is anon-portableextension. && Thebooleanandoperator takes two expressions and returns1if both expressions are non-zero,0otherwise. This isnota short-circuit operator. This is anon-portableextension.||Thebooleanoroperator takes two expressions and returns1if one of the expressions is non-zero,0otherwise. This isnota short-circuit operator. This is anon-portableextension.StatementsThe following items are statements: 1.E2.{S;...;S}3.if(E)S4.if(E)SelseS5.while(E)S6.for(E;E;E)S7. An empty statement 8.break9.continue10.quit11.halt12.limits13. A string of characters, enclosed in double quotes 14.E,...,E15.streamE,...,E16.I(),I(E),I(E,E), and so on, whereIis an identifier for avoidfunction (see theVoidFunctionssubsection of theFUNCTIONSsec- tion). TheEargument(s) may also be arrays of the formI[], which will automatically be turned into array references (see theArrayReferencessubsection of theFUNCTIONSsection) if the correspond- ing parameter in the function definition is an array reference. Numbers 4, 9, 11, 12, 14, 15, and 16 arenon-portableextensions. Also, as anon-portableextension, any or all of the expressions in the header of a for loop may be omitted. If the condition (second expres- sion) is omitted, it is assumed to be a constant1. Thebreakstatement causes a loop to stop iterating and resume execu- tion immediately following a loop. This is only allowed in loops. Thecontinuestatement causes a loop iteration to stop early and re- turns to the start of the loop, including testing the loop condition. This is only allowed in loops. Theifelsestatement does the same thing as in C. Thequitstatement causes bc(1) to quit, even if it is on a branch that will not be executed (it is a compile-time command). Thehaltstatement causes bc(1) to quit, if it is executed. (Unlikequitif it is on a branch of anifstatement that is not executed, bc(1) does not quit.) Thelimitsstatement prints the limits that this bc(1) is subject to. This is like thequitstatement in that it is a compile-time command. An expression by itself is evaluated and printed, followed by a new- line. Both scientific notation and engineering notation are available for printing the results of expressions. Scientific notation is activated by assigning0toobase, and engineering notation is activated by as- signing1toobase. To deactivate them, just assign a different value toobase. Scientific notation and engineering notation are disabled if bc(1) is run with either the-sor-wcommand-line options (or equivalents). Printing numbers in scientific notation and/or engineering notation is anon-portableextension.StringsIf strings appear as a statement by themselves, they are printed with- out a trailing newline. In addition to appearing as a lone statement by themselves, strings can be assigned to variables and array elements. They can also be passed to functions in variable parameters. If any statement that expects a string is given a variable that had a string assigned to it, the statement acts as though it had received a string. If any math operation is attempted on a string or a variable or array element that has been assigned a string, an error is raised, and bc(1) resets (see theRESETsection). Assigning strings to variables and array elements and passing them to functions arenon-portableextensions.StatementThe "expressions" in a\a:\a\b:\b\\:\\e:\\f:\f\n:\n\q:"\r:\r\t:\tAny other character following a backslash causes the backslash and character to be printed as-is. Any non-string expression in a print statement shall be assigned tolast, like any other expression that is printed.StreamStatementThe "expressions in astreamstatement may also be strings. If astreamstatement is given a string, it prints the string as though the string had appeared as its own statement. In other words, thestreamstatement prints strings normally, without a newline. If astreamstatement is given a number, a copy of it is truncated and its absolute value is calculated. The result is then printed as thoughobaseis256and each digit is interpreted as an 8-bit ASCII character, making it a byte stream.OrderofEvaluationAll expressions in a statment are evaluated left to right, except as necessary to maintain order of operations. This means, for example, assuming thatiis equal to0, in the expression a[i++] = i++ the first (or 0th) element ofais set to1, andiis equal to2at the end of the expression. This includes function arguments. Thus, assumingiis equal to0, this means that in the expression x(i++, i++) the first argument passed tox()is0, and the second argument is1, whileiis equal to2before the function starts executing.FUNCTIONSFunction definitions are as follows: define I(I,...,I){ auto I,...,I S;...;S return(E) } AnyIin the parameter list orautolist may be replaced withI[]to make a parameter orautovar an array, and anyIin the parameter list may be replaced with*I[]to make a parameter an array reference. Callers of functions that take array references should not put an as- terisk in the call; they must be called with justI[]like normal array parameters and will be automatically converted into references. As anon-portableextension, the opening brace of adefinestatement may appear on the next line. As anon-portableextension, the return statement may also be in one of the following forms: 1.return2.return()3.returnEThe first two, or not specifying areturnstatement, is equivalent toreturn(0), unless the function is avoidfunction (see theVoidFunc-tionssubsection below).VoidFunctionsFunctions can also bevoidfunctions, defined as follows: define void I(I,...,I){ auto I,...,I S;...;S return } They can only be used as standalone expressions, where such an expres- sion would be printed alone, except in a print statement. Void functions can only use the first tworeturnstatements listed above. They can also omit the return statement entirely. The word "void" is not treated as a keyword; it is still possible to have variables, arrays, and functions namedvoid. The word "void" is only treated specially right after thedefinekeyword. This is anon-portableextension.ArrayReferencesFor any array in the parameter list, if the array is declared in the form *I[] it is areference. Any changes to the array in the function are re- flected, when the function returns, to the array that was passed in. Other than this, all function arguments are passed by value. This is anon-portableextension.LIBRARYAll of the functions below, including the functions in the extended math library (see theExtendedLibrarysubsection below), are available when the-lor--mathlibcommand-line flags are given, except that the extended math library is not available when the-soption, the-wop- tion, or equivalents are given.StandardLibraryThe standard (https://pubs.opengroup.org/onlinepubs/9699919799/utili- ties/bc.html) defines the following functions for the math library:s(x)Returns the sine ofx, which is assumed to be in radians. This is a transcendental function (see theTranscendentalFunc-tionssubsection below).c(x)Returns the cosine ofx, which is assumed to be in radians. This is a transcendental function (see theTranscendentalFunc-tionssubsection below).a(x)Returns the arctangent ofx, in radians. This is a transcendental function (see theTranscendentalFunc-tionssubsection below).l(x)Returns the natural logarithm ofx. This is a transcendental function (see theTranscendentalFunc-tionssubsection below).e(x)Returns the mathematical constanteraised to the power ofx. This is a transcendental function (see theTranscendentalFunc-tionssubsection below).j(x,n)Returns the bessel integer ordern(truncated) ofx. This is a transcendental function (see theTranscendentalFunc-tionssubsection below).ExtendedLibraryThe extended library isnotloaded when the-s/--standardor-w/--warnoptions are given since they are not part of the library defined by the standard (https://pubs.opengroup.org/onlinepubs/9699919799/utili- ties/bc.html). The extended library is anon-portableextension.p(x,y)Calculatesxto the power ofy, even ifyis not an integer, and returns the result to the currentscale. It is an error ifyis negative andxis0. This is a transcendental function (see theTranscendentalFunc-tionssubsection below).r(x,p)Returnsxrounded topdecimal places according to the rounding mode round half away from0(https://en.wikipedia.org/wiki/Round- ing#Round_half_away_from_zero).ceil(x,p)Returnsxrounded topdecimal places according to the rounding mode round away from0(https://en.wikipedia.org/wiki/Round- ing#Rounding_away_from_zero).f(x)Returns the factorial of the truncated absolute value ofx.perm(n,k)Returns the permutation of the truncated absolute value ofnof the truncated absolute value ofk, ifk<=n. If not, it re- turns0.comb(n,k)Returns the combination of the truncated absolute value ofnof the truncated absolute value ofk, ifk<=n. If not, it re- turns0.l2(x)Returns the logarithm base2ofx. This is a transcendental function (see theTranscendentalFunc-tionssubsection below).l10(x)Returns the logarithm base10ofx. This is a transcendental function (see theTranscendentalFunc-tionssubsection below).log(x,b)Returns the logarithm basebofx. This is a transcendental function (see theTranscendentalFunc-tionssubsection below).cbrt(x)Returns the cube root ofx.root(x,n)Calculates the truncated value ofn,r, and returns therth root ofxto the currentscale. Ifris0or negative, this raises an error and causes bc(1) to reset (see theRESETsection). It also raises an error and causes bc(1) to reset ifris even andxis negative.gcd(a,b)Returns the greatest common divisor (factor) of the truncated absolute value ofaand the truncated absolute value ofb.lcm(a,b)Returns the least common multiple of the truncated absolute value ofaand the truncated absolute value ofb.pi(p)Returnspitopdecimal places. This is a transcendental function (see theTranscendentalFunc-tionssubsection below).t(x)Returns the tangent ofx, which is assumed to be in radians. This is a transcendental function (see theTranscendentalFunc-tionssubsection below).a2(y,x)Returns the arctangent ofy/x, in radians. If bothyandxare equal to0, it raises an error and causes bc(1) to reset (see theRESETsection). Otherwise, ifxis greater than0, it re- turnsa(y/x). Ifxis less than0, andyis greater than or equal to0, it returnsa(y/x)+pi. Ifxis less than0, andyis less than0, it returnsa(y/x)-pi. Ifxis equal to0, andyis greater than0, it returnspi/2. Ifxis equal to0, andyis less than0, it returns-pi/2. This function is the same as theatan2()function in many pro- gramming languages. This is a transcendental function (see theTranscendentalFunc-tionssubsection below).sin(x)Returns the sine ofx, which is assumed to be in radians. This is an alias ofs(x). This is a transcendental function (see theTranscendentalFunc-tionssubsection below).cos(x)Returns the cosine ofx, which is assumed to be in radians. This is an alias ofc(x). This is a transcendental function (see theTranscendentalFunc-tionssubsection below).tan(x)Returns the tangent ofx, which is assumed to be in radians. Ifxis equal to1or-1, this raises an error and causes bc(1) to reset (see theRESETsection). This is an alias oft(x). This is a transcendental function (see theTranscendentalFunc-tionssubsection below).atan(x)Returns the arctangent ofx, in radians. This is an alias ofa(x). This is a transcendental function (see theTranscendentalFunc-tionssubsection below).atan2(y,x)Returns the arctangent ofy/x, in radians. If bothyandxare equal to0, it raises an error and causes bc(1) to reset (see theRESETsection). Otherwise, ifxis greater than0, it re- turnsa(y/x). Ifxis less than0, andyis greater than or equal to0, it returnsa(y/x)+pi. Ifxis less than0, andyis less than0, it returnsa(y/x)-pi. Ifxis equal to0, andyis greater than0, it returnspi/2. Ifxis equal to0, andyis less than0, it returns-pi/2. This function is the same as theatan2()function in many pro- gramming languages. This is an alias ofa2(y,x). This is a transcendental function (see theTranscendentalFunc-tionssubsection below).r2d(x)Convertsxfrom radians to degrees and returns the result. This is a transcendental function (see theTranscendentalFunc-tionssubsection below).d2r(x)Convertsxfrom degrees to radians and returns the result. This is a transcendental function (see theTranscendentalFunc-tionssubsection below).frand(p)Generates a pseudo-random number between0(inclusive) and1(exclusive) with the number of decimal digits after the decimal point equal to the truncated absolute value ofp. Ifpis not0, then calling this function will change the value ofseed. Ifpis0, then0is returned, andseedisnotchanged.ifrand(i,p)Generates a pseudo-random number that is between0(inclusive) and the truncated absolute value ofi(exclusive) with the num- ber of decimal digits after the decimal point equal to the trun- cated absolute value ofp. If the absolute value ofiis greater than or equal to2, andpis not0, then calling this function will change the value ofseed; otherwise,0is returned andseedis not changed.srand(x)Returnsxwith its sign flipped with probability0.5. In other words, it randomizes the sign ofx.brand()Returns a random boolean value (either0or1).band(a,b)Takes the truncated absolute value of bothaandband calcu- lates and returns the result of the bitwiseandoperation be- tween them. If you want to use signed two's complement arguments, uses2u(x)to convert.bor(a,b)Takes the truncated absolute value of bothaandband calcu- lates and returns the result of the bitwiseoroperation between them. If you want to use signed two's complement arguments, uses2u(x)to convert.bxor(a,b)Takes the truncated absolute value of bothaandband calcu- lates and returns the result of the bitwisexoroperation be- tween them. If you want to use signed two's complement arguments, uses2u(x)to convert.bshl(a,b)Takes the truncated absolute value of bothaandband calcu- lates and returns the result ofabit-shifted left bybplaces. If you want to use signed two's complement arguments, uses2u(x)to convert.bshr(a,b)Takes the truncated absolute value of bothaandband calcu- lates and returns the truncated result ofabit-shifted right bybplaces. If you want to use signed two's complement arguments, uses2u(x)to convert.bnotn(x,n)Takes the truncated absolute value ofxand does a bitwise not as though it has the same number of bytes as the truncated abso- lute value ofn. If you want to a use signed two's complement argument, uses2u(x)to convert.bnot8(x)Does a bitwise not of the truncated absolute value ofxas though it has8binary digits (1 unsigned byte). If you want to a use signed two's complement argument, uses2u(x)to convert.bnot16(x)Does a bitwise not of the truncated absolute value ofxas though it has16binary digits (2 unsigned bytes). If you want to a use signed two's complement argument, uses2u(x)to convert.bnot32(x)Does a bitwise not of the truncated absolute value ofxas though it has32binary digits (4 unsigned bytes). If you want to a use signed two's complement argument, uses2u(x)to convert.bnot64(x)Does a bitwise not of the truncated absolute value ofxas though it has64binary digits (8 unsigned bytes). If you want to a use signed two's complement argument, uses2u(x)to convert.bnot(x)Does a bitwise not of the truncated absolute value ofxas though it has the minimum number of power of two unsigned bytes. If you want to a use signed two's complement argument, uses2u(x)to convert.brevn(x,n)Runs a bit reversal on the truncated absolute value ofxas though it has the same number of 8-bit bytes as the truncated absolute value ofn. If you want to a use signed two's complement argument, uses2u(x)to convert.brev8(x)Runs a bit reversal on the truncated absolute value ofxas though it has 8 binary digits (1 unsigned byte). If you want to a use signed two's complement argument, uses2u(x)to convert.brev16(x)Runs a bit reversal on the truncated absolute value ofxas though it has 16 binary digits (2 unsigned bytes). If you want to a use signed two's complement argument, uses2u(x)to convert.brev32(x)Runs a bit reversal on the truncated absolute value ofxas though it has 32 binary digits (4 unsigned bytes). If you want to a use signed two's complement argument, uses2u(x)to convert.brev64(x)Runs a bit reversal on the truncated absolute value ofxas though it has 64 binary digits (8 unsigned bytes). If you want to a use signed two's complement argument, uses2u(x)to convert.brev(x)Runs a bit reversal on the truncated absolute value ofxas though it has the minimum number of power of two unsigned bytes. If you want to a use signed two's complement argument, uses2u(x)to convert.broln(x,p,n)Does a left bitwise rotatation of the truncated absolute value ofx, as though it has the same number of unsigned 8-bit bytes as the truncated absolute value ofn, by the number of places equal to the truncated absolute value ofpmodded by the2to the power of the number of binary digits inn8-bit bytes. If you want to a use signed two's complement argument, uses2u(x)to convert.brol8(x,p)Does a left bitwise rotatation of the truncated absolute value ofx, as though it has8binary digits (1unsigned byte), by the number of places equal to the truncated absolute value ofpmod- ded by2to the power of8. If you want to a use signed two's complement argument, uses2u(x)to convert.brol16(x,p)Does a left bitwise rotatation of the truncated absolute value ofx, as though it has16binary digits (2unsigned bytes), by the number of places equal to the truncated absolute value ofpmodded by2to the power of16. If you want to a use signed two's complement argument, uses2u(x)to convert.brol32(x,p)Does a left bitwise rotatation of the truncated absolute value ofx, as though it has32binary digits (2unsigned bytes), by the number of places equal to the truncated absolute value ofpmodded by2to the power of32. If you want to a use signed two's complement argument, uses2u(x)to convert.brol64(x,p)Does a left bitwise rotatation of the truncated absolute value ofx, as though it has64binary digits (2unsigned bytes), by the number of places equal to the truncated absolute value ofpmodded by2to the power of64. If you want to a use signed two's complement argument, uses2u(x)to convert.brol(x,p)Does a left bitwise rotatation of the truncated absolute value ofx, as though it has the minimum number of power of two un- signed 8-bit bytes, by the number of places equal to the trun- cated absolute value ofpmodded by 2 to the power of the number of binary digits in the minimum number of 8-bit bytes. If you want to a use signed two's complement argument, uses2u(x)to convert.brorn(x,p,n)Does a right bitwise rotatation of the truncated absolute value ofx, as though it has the same number of unsigned 8-bit bytes as the truncated absolute value ofn, by the number of places equal to the truncated absolute value ofpmodded by the2to the power of the number of binary digits inn8-bit bytes. If you want to a use signed two's complement argument, uses2u(x)to convert.bror8(x,p)Does a right bitwise rotatation of the truncated absolute value ofx, as though it has8binary digits (1unsigned byte), by the number of places equal to the truncated absolute value ofpmod- ded by2to the power of8. If you want to a use signed two's complement argument, uses2u(x)to convert.bror16(x,p)Does a right bitwise rotatation of the truncated absolute value ofx, as though it has16binary digits (2unsigned bytes), by the number of places equal to the truncated absolute value ofpmodded by2to the power of16. If you want to a use signed two's complement argument, uses2u(x)to convert.bror32(x,p)Does a right bitwise rotatation of the truncated absolute value ofx, as though it has32binary digits (2unsigned bytes), by the number of places equal to the truncated absolute value ofpmodded by2to the power of32. If you want to a use signed two's complement argument, uses2u(x)to convert.bror64(x,p)Does a right bitwise rotatation of the truncated absolute value ofx, as though it has64binary digits (2unsigned bytes), by the number of places equal to the truncated absolute value ofpmodded by2to the power of64. If you want to a use signed two's complement argument, uses2u(x)to convert.bror(x,p)Does a right bitwise rotatation of the truncated absolute value ofx, as though it has the minimum number of power of two un- signed 8-bit bytes, by the number of places equal to the trun- cated absolute value ofpmodded by 2 to the power of the number of binary digits in the minimum number of 8-bit bytes. If you want to a use signed two's complement argument, uses2u(x)to convert.bmodn(x,n)Returns the modulus of the truncated absolute value ofxby2to the power of the multiplication of the truncated absolute value ofnand8. If you want to a use signed two's complement argument, uses2u(x)to convert.bmod8(x,n)Returns the modulus of the truncated absolute value ofxby2to the power of8. If you want to a use signed two's complement argument, uses2u(x)to convert.bmod16(x,n)Returns the modulus of the truncated absolute value ofxby2to the power of16. If you want to a use signed two's complement argument, uses2u(x)to convert.bmod32(x,n)Returns the modulus of the truncated absolute value ofxby2to the power of32. If you want to a use signed two's complement argument, uses2u(x)to convert.bmod64(x,n)Returns the modulus of the truncated absolute value ofxby2to the power of64. If you want to a use signed two's complement argument, uses2u(x)to convert.bunrev(t)Assumestis a bitwise-reversed number with an extra set bit one place more significant than the real most significant bit (which was the least significant bit in the original number). This number is reversed and returned without the extra set bit. This function is used to implement other bitwise functions; it is not meant to be used by users, but it can be.plz(x)Ifxis not equal to0and greater that-1and less than1, it is printed with a leading zero, regardless of the use of the-zoption (see theOPTIONSsection) and without a trailing newline. Otherwise,xis printed normally, without a trailing newline.plznl(x)Ifxis not equal to0and greater that-1and less than1, it is printed with a leading zero, regardless of the use of the-zoption (see theOPTIONSsection) and with a trailing newline. Otherwise,xis printed normally, with a trailing newline.pnlz(x)Ifxis not equal to0and greater that-1and less than1, it is printed without a leading zero, regardless of the use of the-zoption (see theOPTIONSsection) and without a trailing new- line. Otherwise,xis printed normally, without a trailing newline.pnlznl(x)Ifxis not equal to0and greater that-1and less than1, it is printed without a leading zero, regardless of the use of the-zoption (see theOPTIONSsection) and with a trailing newline. Otherwise,xis printed normally, with a trailing newline.ubytes(x)Returns the numbers of unsigned integer bytes required to hold the truncated absolute value ofx.sbytes(x)Returns the numbers of signed, two's-complement integer bytes required to hold the truncated value ofx.s2u(x)Returnsxif it is non-negative. If itisnegative, then it calculates whatxwould be as a 2's-complement signed integer and returns the non-negative integer that would have the same representation in binary.s2un(x,n)Returnsxif it is non-negative. If itisnegative, then it calculates whatxwould be as a 2's-complement signed integer withnbytes and returns the non-negative integer that would have the same representation in binary. Ifxcannot fit inton2's-complement signed bytes, it is truncated to fit.hex(x)Outputs the hexadecimal (base16) representation ofx. This is avoidfunction (see theVoidFunctionssubsection of theFUNCTIONSsection).binary(x)Outputs the binary (base2) representation ofx. This is avoidfunction (see theVoidFunctionssubsection of theFUNCTIONSsection).output(x,b)Outputs the basebrepresentation ofx. This is avoidfunction (see theVoidFunctionssubsection of theFUNCTIONSsection).uint(x)Outputs the representation, in binary and hexadecimal, ofxas an unsigned integer in as few power of two bytes as possible. Both outputs are split into bytes separated by spaces. Ifxis not an integer or is negative, an error message is printed instead, but bc(1) is not reset (see theRESETsection). This is avoidfunction (see theVoidFunctionssubsection of theFUNCTIONSsection).int(x)Outputs the representation, in binary and hexadecimal, ofxas a signed, two's-complement integer in as few power of two bytes as possible. Both outputs are split into bytes separated by spa- ces. Ifxis not an integer, an error message is printed instead, but bc(1) is not reset (see theRESETsection). This is avoidfunction (see theVoidFunctionssubsection of theFUNCTIONSsection).uintn(x,n)Outputs the representation, in binary and hexadecimal, ofxas an unsigned integer innbytes. Both outputs are split into bytes separated by spaces. Ifxis not an integer, is negative, or cannot fit intonbytes, an error message is printed instead, but bc(1) is not reset (see theRESETsection). This is avoidfunction (see theVoidFunctionssubsection of theFUNCTIONSsection).intn(x,n)Outputs the representation, in binary and hexadecimal, ofxas a signed, two's-complement integer innbytes. Both outputs are split into bytes separated by spaces. Ifxis not an integer or cannot fit intonbytes, an error mes- sage is printed instead, but bc(1) is not reset (see theRESETsection). This is avoidfunction (see theVoidFunctionssubsection of theFUNCTIONSsection).uint8(x)Outputs the representation, in binary and hexadecimal, ofxas an unsigned integer in1byte. Both outputs are split into bytes separated by spaces. Ifxis not an integer, is negative, or cannot fit into1byte, an error message is printed instead, but bc(1) is not reset (see theRESETsection). This is avoidfunction (see theVoidFunctionssubsection of theFUNCTIONSsection).int8(x)Outputs the representation, in binary and hexadecimal, ofxas a signed, two's-complement integer in1byte. Both outputs are split into bytes separated by spaces. Ifxis not an integer or cannot fit into1byte, an error mes- sage is printed instead, but bc(1) is not reset (see theRESETsection). This is avoidfunction (see theVoidFunctionssubsection of theFUNCTIONSsection).uint16(x)Outputs the representation, in binary and hexadecimal, ofxas an unsigned integer in2bytes. Both outputs are split into bytes separated by spaces. Ifxis not an integer, is negative, or cannot fit into2bytes, an error message is printed instead, but bc(1) is not reset (see theRESETsection). This is avoidfunction (see theVoidFunctionssubsection of theFUNCTIONSsection).int16(x)Outputs the representation, in binary and hexadecimal, ofxas a signed, two's-complement integer in2bytes. Both outputs are split into bytes separated by spaces. Ifxis not an integer or cannot fit into2bytes, an error mes- sage is printed instead, but bc(1) is not reset (see theRESETsection). This is avoidfunction (see theVoidFunctionssubsection of theFUNCTIONSsection).uint32(x)Outputs the representation, in binary and hexadecimal, ofxas an unsigned integer in4bytes. Both outputs are split into bytes separated by spaces. Ifxis not an integer, is negative, or cannot fit into4bytes, an error message is printed instead, but bc(1) is not reset (see theRESETsection). This is avoidfunction (see theVoidFunctionssubsection of theFUNCTIONSsection).int32(x)Outputs the representation, in binary and hexadecimal, ofxas a signed, two's-complement integer in4bytes. Both outputs are split into bytes separated by spaces. Ifxis not an integer or cannot fit into4bytes, an error mes- sage is printed instead, but bc(1) is not reset (see theRESETsection). This is avoidfunction (see theVoidFunctionssubsection of theFUNCTIONSsection).uint64(x)Outputs the representation, in binary and hexadecimal, ofxas an unsigned integer in8bytes. Both outputs are split into bytes separated by spaces. Ifxis not an integer, is negative, or cannot fit into8bytes, an error message is printed instead, but bc(1) is not reset (see theRESETsection). This is avoidfunction (see theVoidFunctionssubsection of theFUNCTIONSsection).int64(x)Outputs the representation, in binary and hexadecimal, ofxas a signed, two's-complement integer in8bytes. Both outputs are split into bytes separated by spaces. Ifxis not an integer or cannot fit into8bytes, an error mes- sage is printed instead, but bc(1) is not reset (see theRESETsection). This is avoidfunction (see theVoidFunctionssubsection of theFUNCTIONSsection).hex_uint(x,n)Outputs the representation of the truncated absolute value ofxas an unsigned integer in hexadecimal usingnbytes. Not all of the value will be output ifnis too small. This is avoidfunction (see theVoidFunctionssubsection of theFUNCTIONSsection).binary_uint(x,n)Outputs the representation of the truncated absolute value ofxas an unsigned integer in binary usingnbytes. Not all of the value will be output ifnis too small. This is avoidfunction (see theVoidFunctionssubsection of theFUNCTIONSsection).output_uint(x,n)Outputs the representation of the truncated absolute value ofxas an unsigned integer in the currentobase(see theSYNTAXsec- tion) usingnbytes. Not all of the value will be output ifnis too small. This is avoidfunction (see theVoidFunctionssubsection of theFUNCTIONSsection).output_byte(x,i)Outputs byteiof the truncated absolute value ofx, where0is the least significant byte andnumber_of_bytes-1is the most significant byte. This is avoidfunction (see theVoidFunctionssubsection of theFUNCTIONSsection).TranscendentalFunctionsAll transcendental functions can return slightly inaccurate results (up to 1 ULP (https://en.wikipedia.org/wiki/Unit_in_the_last_place)). This is unavoidable, and this article (https://people.eecs.berke- ley.edu/~wkahan/LOG10HAF.TXT) explains why it is impossible and unnec- essary to calculate exact results for the transcendental functions. Because of the possible inaccuracy, I recommend that users call those functions with the precision (scale) set to at least 1 higher than is necessary. If exact results areabsolutelyrequired, users can double the precision (scale) and then truncate. The transcendental functions in the standard math library are:os(x)oc(x)oa(x)ol(x)oe(x)oj(x,n)The transcendental functions in the extended math library are:ol2(x)ol10(x)olog(x,b)opi(p)ot(x)oa2(y,x)osin(x)ocos(x)otan(x)oatan(x)oatan2(y,x)or2d(x)od2r(x)RESETWhen bc(1) encounters an error or a signal that it has a non-default handler for, it resets. This means that several things happen. First, any functions that are executing are stopped and popped off the stack. The behavior is not unlike that of exceptions in programming languages. Then the execution point is set so that any code waiting to execute (after all functions returned) is skipped. Thus, when bc(1) resets, it skips any remaining code waiting to be exe- cuted. Then, if it is interactive mode, and the error was not a fatal error (see theEXITSTATUSsection), it asks for more input; otherwise, it exits with the appropriate return code. Note that this reset behavior is different from the GNU bc(1), which attempts to start executing the statement right after the one that caused an error.PERFORMANCEMost bc(1) implementations usechartypes to calculate the value of1decimal digit at a time, but that can be slow. This bc(1) does some- thing different. It uses large integers to calculate more than1decimal digit at a time. If built in a environment whereBC_LONG_BIT(see theLIMITSsec- tion) is64, then each integer has9decimal digits. If built in an environment whereBC_LONG_BITis32then each integer has4decimal digits. This value (the number of decimal digits per large integer) is calledBC_BASE_DIGS. The actual values ofBC_LONG_BITandBC_BASE_DIGScan be queried with thelimitsstatement. In addition, this bc(1) uses an even larger integer for overflow check- ing. This integer type depends on the value ofBC_LONG_BIT, but is al- ways at least twice as large as the integer type used to store digits.LIMITSThe following are the limits on bc(1):BC_LONG_BITThe number of bits in thelongtype in the environment where bc(1) was built. This determines how many decimal digits can be stored in a single large integer (see thePERFORMANCEsection).BC_BASE_DIGSThe number of decimal digits per large integer (see thePERFOR-MANCEsection). Depends onBC_LONG_BIT.BC_BASE_POWThe max decimal number that each large integer can store (seeBC_BASE_DIGS) plus1. Depends onBC_BASE_DIGS.BC_OVERFLOW_MAXThe max number that the overflow type (see thePERFORMANCEsec- tion) can hold. Depends onBC_LONG_BIT.BC_BASE_MAXThe maximum output base. Set atBC_BASE_POW.BC_DIM_MAXThe maximum size of arrays. Set atSIZE_MAX-1.BC_SCALE_MAXThe maximumscale. Set atBC_OVERFLOW_MAX-1.BC_STRING_MAXThe maximum length of strings. Set atBC_OVERFLOW_MAX-1.BC_NAME_MAXThe maximum length of identifiers. Set atBC_OVERFLOW_MAX-1.BC_NUM_MAXThe maximum length of a number (in decimal digits), which in- cludes digits after the decimal point. Set atBC_OVER-FLOW_MAX-1.BC_RAND_MAXThe maximum integer (inclusive) returned by therand()operand. Set at2^BC_LONG_BIT-1. Exponent The maximum allowable exponent (positive or negative). Set atBC_OVERFLOW_MAX. Number of vars The maximum number of vars/arrays. Set atSIZE_MAX-1. The actual values can be queried with thelimitsstatement. These limits are meant to be effectively non-existent; the limits are so large (at least on 64-bit machines) that there should not be any point at which they become a problem. In fact, memory should be ex- hausted before these limits should be hit.ENVIRONMENT VARIABLESbc(1) recognizes the following environment variables:POSIXLY_CORRECTIf this variable exists (no matter the contents), bc(1) behaves as if the-soption was given.BC_ENV_ARGSThis is another way to give command-line arguments to bc(1). They should be in the same format as all other command-line ar- guments. These are always processed first, so any files given inBC_ENV_ARGSwill be processed before arguments and files given on the command-line. This gives the user the ability to set up "standard" options and files to be used at every invoca- tion. The most useful thing for such files to contain would be useful functions that the user might want every time bc(1) runs. The code that parsesBC_ENV_ARGSwill correctly handle quoted arguments, but it does not understand escape sequences. For ex- ample, the string"/home/gavin/somebcfile.bc"will be cor- rectly parsed, but the string"/home/gavin/some"bc"file.bc"will include the backslashes. The quote parsing will handle either kind of quotes,'or". Thus, if you have a file with any number of single quotes in the name, you can use double quotes as the outside quotes, as in"some`bc'file.bc", and vice versa if you have a file with dou- ble quotes. However, handling a file with both kinds of quotes inBC_ENV_ARGSis not supported due to the complexity of the parsing, though such files are still supported on the command- line where the parsing is done by the shell.BC_LINE_LENGTHIf this environment variable exists and contains an integer that is greater than1and is less thanUINT16_MAX(2^16-1), bc(1) will output lines to that length, including the backslash (\). The default line length is70. The special value of0will disable line length checking and print numbers without regard to line length and without back- slashes and newlines.BC_BANNERIf this environment variable exists and contains an integer, then a non-zero value activates the copyright banner when bc(1) is in interactive mode, while zero deactivates it. If bc(1) is not in interactive mode (see theINTERACTIVEMODEsection), then this environment variable has no effect because bc(1) does not print the banner when not in interactive mode. This environment variable overrides the default, which can be queried with the-hor--helpoptions.BC_SIGINT_RESETIf bc(1) is not in interactive mode (see theINTERACTIVEMODEsection), then this environment variable has no effect because bc(1) exits onSIGINTwhen not in interactive mode. However, when bc(1) is in interactive mode, then if this envi- ronment variable exists and contains an integer, a non-zero value makes bc(1) reset onSIGINT, rather than exit, and zero makes bc(1) exit. If this environment variable exists and isnotan integer, then bc(1) will exit onSIGINT. This environment variable overrides the default, which can be queried with the-hor--helpoptions.BC_TTY_MODEIf TTY mode isnotavailable (see theTTYMODEsection), then this environment variable has no effect. However, when TTY mode is available, then if this environment variable exists and contains an integer, then a non-zero value makes bc(1) use TTY mode, and zero makes bc(1) not use TTY mode. This environment variable overrides the default, which can be queried with the-hor--helpoptions.BC_PROMPTIf TTY mode isnotavailable (see theTTYMODEsection), then this environment variable has no effect. However, when TTY mode is available, then if this environment variable exists and contains an integer, a non-zero value makes bc(1) use a prompt, and zero or a non-integer makes bc(1) not use a prompt. If this environment variable does not exist andBC_TTY_MODEdoes, then the value of theBC_TTY_MODEenvironment variable is used. This environment variable and theBC_TTY_MODEenvironment vari- able override the default, which can be queried with the-hor--helpoptions.BC_EXPR_EXITIf any expressions or expression files are given on the command- line with-e,--expression,-f, or--file, then if this environ- ment variable exists and contains an integer, a non-zero value makes bc(1) exit after executing the expressions and expression files, and a non-zero value makes bc(1) not exit. This environment variable overrides the default, which can be queried with the-hor--helpoptions.EXIT STATUSbc(1) returns the following exit statuses:0No error.1A math error occurred. This follows standard practice of using1for expected errors, since math errors will happen in the process of normal execution. Math errors include divide by0, taking the square root of a negative number, using a negative number as a bound for the pseudo-random number generator, attempting to convert a negative number to a hardware integer, overflow when converting a number to a hardware integer, overflow when calculating the size of a number, and attempting to use a non-integer where an integer is required. Converting to a hardware integer happens for the second operand of the power (^), places (@), left shift (<<), and right shift (>>) operators and their corresponding assignment operators.2A parse error occurred. Parse errors include unexpectedEOF, using an invalid character, failing to find the end of a string or comment, using a token where it is invalid, giving an invalid expression, giving an in- valid print statement, giving an invalid function definition, attempting to assign to an expression that is not a named ex- pression (see theNamedExpressionssubsection of theSYNTAXsection), giving an invalidautolist, having a duplicateauto/function parameter, failing to find the end of a code block, attempting to return a value from avoidfunction, at- tempting to use a variable as a reference, and using any exten- sions when the option-sor any equivalents were given.3A runtime error occurred. Runtime errors include assigning an invalid number to any global (ibase,obase, orscale), giving a bad expression to aread()call, callingread()inside of aread()call, type errors, pass- ing the wrong number of arguments to functions, attempting to call an undefined function, and attempting to use avoidfunc- tion call as a value in an expression.4A fatal error occurred. Fatal errors include memory allocation errors, I/O errors, fail- ing to open files, attempting to use files that do not have only ASCII characters (bc(1) only accepts ASCII characters), attempt- ing to open a directory as a file, and giving invalid command- line options. The exit status4is special; when a fatal error occurs, bc(1) always exits and returns4, no matter what mode bc(1) is in. The other statuses will only be returned when bc(1) is not in interac- tive mode (see theINTERACTIVEMODEsection), since bc(1) resets its state (see theRESETsection) and accepts more input when one of those errors occurs in interactive mode. This is also the case when interac- tive mode is forced by the-iflag or--interactiveoption. These exit statuses allow bc(1) to be used in shell scripting with er- ror checking, and its normal behavior can be forced by using the-iflag or--interactiveoption.INTERACTIVE MODEPer the standard (https://pubs.opengroup.org/on- linepubs/9699919799/utilities/bc.html), bc(1) has an interactive mode and a non-interactive mode. Interactive mode is turned on automati- cally when bothstdinandstdoutare hooked to a terminal, but the-iflag and--interactiveoption can turn it on in other situations. In interactive mode, bc(1) attempts to recover from errors (see theRE-SETsection), and in normal execution, flushesstdoutas soon as execu- tion is done for the current input. bc(1) may also reset onSIGINTin- stead of exit, depending on the contents of, or default for, theBC_SIGINT_RESETenvironment variable (see theENVIRONMENTVARIABLESsection).TTY MODEIfstdin,stdout, andstderrare all connected to a TTY, then "TTY mode" is considered to be available, and thus, bc(1) can turn on TTY mode, subject to some settings. If there is the environment variableBC_TTY_MODEin the environment (see theENVIRONMENTVARIABLESsection), then if that environment vari- able contains a non-zero integer, bc(1) will turn on TTY mode whenstdin,stdout, andstderrare all connected to a TTY. If theBC_TTY_MODEenvironment variable exists but isnota non-zero integer, then bc(1) will not turn TTY mode on. If the environment variableBC_TTY_MODEdoesnotexist, the default setting is used. The default setting can be queried with the-hor--helpoptions. TTY mode is different from interactive mode because interactive mode is required in the bc(1) specification (https://pubs.opengroup.org/on- linepubs/9699919799/utilities/bc.html), and interactive mode requires onlystdinandstdoutto be connected to a terminal.Command-LineHistoryCommand-line history is only enabled if TTY mode is, i.e., thatstdin,stdout, andstderrare connected to a TTY and theBC_TTY_MODEenviron- ment variable (see theENVIRONMENTVARIABLESsection) and its default do not disable TTY mode. See theCOMMANDLINEHISTORYsection for more information.PromptIf TTY mode is available, then a prompt can be enabled. Like TTY mode itself, it can be turned on or off with an environment variable:BC_PROMPT(see theENVIRONMENTVARIABLESsection). If the environment variableBC_PROMPTexists and is a non-zero integer, then the prompt is turned on whenstdin,stdout, andstderrare con- nected to a TTY and the-Pand--no-promptoptions were not used. The read prompt will be turned on under the same conditions, except that the-Rand--no-read-promptoptions must also not be used. However, ifBC_PROMPTdoes not exist, the prompt can be enabled or dis- abled with theBC_TTY_MODEenvironment variable, the-Pand--no-promptoptions, and the-Rand--no-read-promptoptions. See theENVIRONMENTVARIABLESandOPTIONSsections for more details.SIGNAL HANDLINGSending aSIGINTwill cause bc(1) to do one of two things. If bc(1) is not in interactive mode (see theINTERACTIVEMODEsection), or theBC_SIGINT_RESETenvironment variable (see theENVIRONMENTVARI-ABLESsection), or its default, is either not an integer or it is zero, bc(1) will exit. However, if bc(1) is in interactive mode, and theBC_SIGINT_RESETor its default is an integer and non-zero, then bc(1) will stop executing the current input and reset (see theRESETsection) upon receiving aSIGINT. Note that "current input" can mean one of two things. If bc(1) is pro- cessing input fromstdinin interactive mode, it will ask for more in- put. If bc(1) is processing input from a file in interactive mode, it will stop processing the file and start processing the next file, if one exists, or ask for input fromstdinif no other file exists. This means that if aSIGINTis sent to bc(1) as it is executing a file, it can seem as though bc(1) did not respond to the signal since it will immediately start executing the next file. This is by design; most files that users execute when interacting with bc(1) have function def- initions, which are quick to parse. If a file takes a long time to ex- ecute, there may be a bug in that file. The rest of the files could still be executed without problem, allowing the user to continue.SIGTERMandSIGQUITcause bc(1) to clean up and exit, and it uses the default handler for all other signals. The one exception isSIGHUP; in that case, and only when bc(1) is in TTY mode (see theTTYMODEsec- tion), aSIGHUPwill cause bc(1) to clean up and exit.COMMAND LINE HISTORYbc(1) supports interactive command-line editing. If bc(1) can be in TTY mode (see theTTYMODEsection), history can be enabled. This means that command-line history can only be enabled whenstdin,stdout, andstderrare all connected to a TTY. Like TTY mode itself, it can be turned on or off with the environment variableBC_TTY_MODE(see theENVIRONMENTVARIABLESsection). If history is enabled, previous lines can be recalled and edited with the arrow keys.Note: tabs are converted to 8 spaces.LOCALESThis bc(1) ships with support for adding error messages for different locales and thus, supportsLC_MESSAGES.SEE ALSOdc(1)STANDARDSbc(1) is compliant with the IEEE Std 1003.1-2017 ("POSIX.1-2017") (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html) specification. The flags-efghiqsvVw, all long options, and the exten- sions noted above are extensions to that specification. Note that the specification explicitly says that bc(1) only accepts numbers that use a period (.) as a radix point, regardless of the value ofLC_NUMERIC. This bc(1) supports error messages for different locales, and thus, it supportsLC_MESSAGES.BUGSNone are known. Report bugs at https://git.yzena.com/gavin/bc.AUTHORSGavin D. Howard <gavin@yzena.com> and contributors. Gavin D. Howard June 2021 BC(1)

NAME | SYNOPSIS | DESCRIPTION | OPTIONS | STDIN | STDOUT | STDERR | SYNTAX | FUNCTIONS | LIBRARY | RESET | PERFORMANCE | LIMITS | ENVIRONMENT VARIABLES | EXIT STATUS | INTERACTIVE MODE | TTY MODE | SIGNAL HANDLING | COMMAND LINE HISTORY | LOCALES | SEE ALSO | STANDARDS | BUGS | AUTHORS

Want to link to this manual page? Use this URL:

<https://man.freebsd.org/cgi/man.cgi?query=bc&manpath=FreeBSD+13.1-RELEASE+and+Ports>