You can use bc to perform arithmetical calculations. bc is an interactive program for a C-like input language.
Syntax
bc[ -l][ file ...] |
-l stands for /usr/lib/lib.b, which is a library containing bc programs for various mathematical functions. The -l option must be specified if you want to use any the following functions: s(x) sine c(x) cosine e(x) base e exponential function l(x) natural logarithm a(x) arctangent j(n,x) n-th order Bessel function
Name of file containing a bc program. You may specify more than one file. When all statements from all files have been processed, bc reads from standard input. You can then enter further statements. file not specified: |
Elements of bc programs
A bc program consists of
definitions
statements
comments
The following symbols are used in defining the structure of bc programs:
L | (L - letter) stands for one of the letters a-z |
E | (E - expression) stands for an expression |
S | (S - statement) stands for a statement |
Comments
Comments are enclosed in /*...*/ as in C.
Statements
Statements in bc can be:
Expressions (see Expressions)
The value of a statement that is an expression is printed unless the main operator is an assignment.
Blocks (grouped statements): {S; ...; S}
Conditional statement: if (E) S
If expression E is true, i.e. has a non-zero value, then statement S is executed.
Iteration statements:
while (E) S
Expression E is evaluated and if it has a non-zero value, statement S is executed. E is then evaluated again, and S is executed again if E is still non-zero. This process is repeated for as long as E has a non-zero value.for (E; E; E) S
First, the first expression is evaluated. Next, the second expression is evaluated and if it has a non-zero value, statement S is executed. Lastly, the third expression is evaluated. Then the second expression is evaluated again and statement S is again executed if it is non-zero, and so on. Unlike in C programs, a for statement must always contain three expressions.
Jump statement: break
The break statement can be used only within an iteration statement. It causes termination of the nearest while or for statement. Program execution continues with the statement that follows the terminated iteration statement.
Termination statement: quit
The quit statement stops execution of a bc program. The quit statement is interpreted as soon as it is read, not when the bc program is executed.
You can separate statements from one another with a semicolon or a newline character.
Example
The following bc program terminates immediately without printing the value of a:
a=5 if (a>10) quit a)
Expressions
Expressions consist of operands and operators.
Operands are names or arbitrarily long numbers with optional sign and decimal point.
Names
L | simple variables |
L | function names |
L[E] | array elements |
ibase | base (radix) for input numbers, default: 10 |
obase | base (radix) for output numbers, default: 10 |
scale | number of fractional digits, default: 0 |
If arrays are used as function arguments or defined as automatic variables, empty square brackets must follow the array name.
The same name may be used simultaneously for an array, a function, and a simple variable. All variables are global to a bc program.
Other operands
(E) | result of E |
sqrt(E) | square root of E |
length(E) | number of significant decimal digits in E |
scale(E) | number of fractional digits in E |
Operators
+ – * / | addition, subtraction, multiplication, division |
^ | power operator |
% | remainder of integer division (can now also be applied to floatingpoint numbers |
++ -- | increment and decrement operators, which can be applied to names in prefix or postfix notation |
< <= == >= > != | relational operators (less than, less than or equal to, equal to, greater than or equal to, greater than, not equal to) |
= | assignment operator |
=@ | compound assignment operators, where a=@b is the same as a=a@b. @ can be any of the operators + - * / ^ or % |
The logical operators && and || are not recognized by the bc command.
Function definition
define L (L, ...,L) { auto L, ...,L S; ...;S return (E) }
Example
define p(x) { auto q q = p * p return (q) }
Declaring the identifiers of a function as auto restricts their scope to that function. All function arguments are passed by value.
Functions in the math library /usr/lib/lib.b
Definitions of the mathematical functions listed below are contained in the library /usr/lib/lib.b. The functions can be accessed by calling bc with option -l.
s(x) sine c(x) cosine e(x) base e exponential function l(x) natural logarithm a(x) arctangent j(n,x) n-th order Bessel function
x values in mathematical functions must be specified in absolute radian measure.
If you have write permission for /usr/lib/lib.b, you can add definitions of further functions and also modify or delete existing ones.
Defining bases for input and output numbers
With ibase and obase you can specify the base used for interpreting input and output values (input and output number radix). The following rules apply:
If you do not explicitly assign values to ibase and obase, input numbers are interpreted as decimal and results are output in decimal.
If you have already defined the input base with an ibase=n statement, the number that you use to define the output base in an obase=m statement must be in input base n as well.
Example
The input base is to be 2, the output base 16:
$ bc ibase=2 obase=10000 10100000/1010 10
Fractional digits
Each expression E in bc is associated with a specific number of fractional digits. You can use the scale variable to inspect or change this number and the scale(E) function just to inspect it.
Example
In the following example the value of operand a is divided by the value of operand b with the scale variable initially left unset: the result contains no fractional digits. Then scale is assigned a value of 8: the result of the division is now correct to 8 places after the decimal point.
Finally we inspect the number of fractional digits in the result and the value of scale.
CTRL+D or @@d
|
If you join two expressions using an operator, the number of fractional digits associated with the result is governed by a rule specific to the operator you use. The rules for bc operators are described below. Various symbols are used in the descriptions:
a = first operand
b = second operand
R = number of fractional digits in the result of a calculation
A = scale(a)
B = scale(b)
-
++
--
The unary minus sign and the increment and decrement operators ++ and -- (in prefix and postfix notation) do not affect the number of fractional digits.
Rule: scale(E) = scale (-E) = scale(--E) = scale(++E) ...
Example
a is assigned a value with three fractional digits. The query function scale(a) here always returns 3, regardless of whether a has a -, -- or ++ operator and regardless of the fact that scale was previously assigned a different value:
CTRL+D or @@d
|
+
-
With the binary operators + and -, R is equal to the number of fractional digits in the operand with the most fractional digits, regardless of whether you have previously assigned scale some other value.
Rule: R = max(A,B)
Example
The scale variable is assigned a value of 1. Operand a is assigned a value with 2 fractional digits, b a value with three fractional digits. Thus b has more fractional digits than a, and also more than scale. The query function returns 3 for both operands, the greater number in b taking precedence.
CTRL+D or @@d
|
*
With multiplications, a value previously assigned to scale is significant: bc first calculates max, which is the highest of the values scale, A and B. It then forms the sum of A and B and compares this value with max. R is then the lower (min) of these two values.
Rule: R = min (A+B, max (scale, A, B))
Example
scale has a value of 9, A and B are both 1. Thus the highest of the three values is 9. The sum of the number of fractional digits in the two operands is 2. The number of fractional digits in the result of the multiplication is the lower from the comparison of max and this sum, which is 2.
CTRL+D or @@d
|
/
With divisions, the precision of the result is equal to the value of scale:
Rule: R = scale
Example
scale is first given a value of 8. Then the operands are assigned integer values. The result is also an integer. In spite of that, the query function returns 8, and the result is shown correct to 8 places after the decimal point.
CTRL+D or @@d
|
^
With the power operator, R is formed as follows:
If the integer exponent e is equal to or greater than 0:
bc takes the higher (max) of the two values scale and A. It then multiplies A by the absolute value m of the exponent, compares the result with max, and takes the lower of the two values.
Rule: R = min (A*m, max (scale, A))
If the integer exponent e is less than 0:
The precision of the result is equal to the value of scale.
Rule: R = scale
Example 1
scale is given a value of 7. a has one fractional digit, and the absolute value of exponent e is 4, i.e. greater than 0. The higher value from the comparison of scale and a is 7. However, the result of multiplying a and m is 4. Thus the number of fractional digits after exponentiation is 4:
CTRL+D or @@d
|
Example 2
However, if you set the exponent e to -4, the number of fractional digits is equal to the value of scale:
CTRL+D or @@d
|
==@
With the assignment operators, the value of R is equal to that of A after assignment. For a given compound operator =@, the rule for calculating the number of fractional digits is the same as for the corresponding simple operator @.
Rules: R = scale(b) and R = scale(a@b)
Example 1
a is assigned a number with one fractional digit, b a number with two fractional digits: scale(a) is 1 and scale(b) is 2. If you inspect scale(a) after assigning the operands, bc returns a value of 2, which is scale(b). If you then inspect a again, the value returned is the value assigned to b:
CTRL+D or @@d
|
Example 2
a is assigned a number with two fractional digits, b a number with three. In the ffunction call, a is assigned the value resulting from adding the two operands. bc sees the number of fractional digits in the result of an addition as being equal the number of fractional digits in the operand with the most fractional digits. After assignment a has the same number of digits, i.e. three:
CTRL+D or @@d
|
%
With remaindering, if the value of scale is non-zero, the result is computed as follows:
a%b = a - (a / b) * b
First the division is performed using the precision of scale. The precision of the multiplication by b is equal to:
scale + B
In other words the multiplication is performed with full precision. Thus here the % operator can be used as a measure of the precision with which the division is performed.
Finally R is whichever is the higher of A and (scale + B).
Rule: R = max ((scale + B), A)
Example
scale has a value of 4, a and b each have one fractional digit. The result of remaindering has five fractional digits:
CTRL+D or @@d
|
File
/usr/lib/lib.b Math library |
Locale
The following environment variables affect the execution of bc: LANG Provide a default value for the internationalization variables that are unset or null. If LANG is unset of null, the corresponding value from the implementation-specific default locale will be used. If any of the internationalization variables contains an invalid setting, the utility will behave as if none of the variables had been defined. LC_ALL If set to a non-empty string value, override the values of all the other internationalization variables. LC_CTYPE Determine the locale for the interpretation of sequences of bytes of text data as characters (for example, single- as opposed to multi-byte characters in arguments and input files). LC_MESSAGES Determine the locale that should be used to affect the format and contents of diagnostic messages written to standard error. NLSPATH Determine the location of message catalogs for the processing of LC_MESSAGES. |
Example 1
Addition, subtraction, multiplication, and division of numbers. Non-integer results are to have 2 digits after the decimal point: $ bc scale=2 3+7 10 8-15 -7 7*6 42 3/5 .60 quit $ |
Example 2
Defining a function to compute an approximate value of the exponential function. scale=20 define e(x){ auto a, b, c, i, s a = 1 b = 1 s = 1 for(i=1;1==1;i++){ a = a*x b = b*i c = a/b if(c==0) return (s) s = s+c } } The termination criterion of the for loop is contained in the body of the loop (if(c==0)) and is not given by the second expression of the for statement as is usually the case. In a C program, the second expression of the for statement would simply be omitted; but in a bc program the for statement must always have 3 expressions. The expression 1==1, which is always true, has been inserted for this reason. |
Example 3
Printing approximate values of the exponential function of the first ten integers. for(i=1;i<=10;i++) e(i) |
Example 4
Printing the squares of the integers 1 to 4: $ bc for(i=1;i<5;i++) {i*i} 1 4 9 16 quit
|
See also
expr, let |