Guide to Unix/Explanations/bc

From Wikibooks, open books for an open world
Jump to navigation Jump to search

bc is an arbitrary-precision calculator language. The arbitrary-precision means that numbers can contain an arbitrary number of digits before the decimal point, limited by memory; most other languages limit numbers to eight bytes at most. The number of digits after the decimal point is per default zero, but can be set to a fixed number called "scale".

"bc" is often called using the "-l" option. The option loads the standard library containing mostly trigonometric functions available as single letters, and sets the number of decimal places for division to 20.

Overview

Bc at a glance:

echo '2*17' | bc              # Feeds the math expression into bc, resulting in 34
echo '2^5' | bc               # Exponentiation
echo '2+3;4*5' | bc           # Two calculations, output on separate lines
echo '1/3' | bc               # Zero: the default decimal precision is 0
echo '1/3' | bc -l            # 0.33...: -l raises the decimal precision to 20
echo 'sqrt(2)' | bc -l
echo 'sqrt(2.00)' | bc        # 1.41; sqrt is affected by the argument precision
echo 's(1/3)' | bc -l         # sin(1/3): sin is there via -l loading the library
echo 's(1)+c(1)+a(1)+l(1)+e(1)' | bc -l  # sin(1)+cos(1)+atan(1)+ln(1)+exp(1)
echo 'scale=100;4*a(1)' | bc -l  # Pi, 3.1415..., with 100 decimal digit precision
echo 'obase=2;12' | bc        # Yields 12 converted to binary by setting output base
echo 'obase=2;1/3' | bc -l    # Yields .01010101...: output base affects fractions
echo 'ibase=16;1F' | bc       # Yields 31; sets the input base
echo '4!=5' | bc -l           # 1 for True: 4 differs from 5
echo 'if(1!=0)2' | bc -l      # if
echo 'i=1;r=1;while(i<=10){r*=i;i+=1};r' | bc -l  # Factorial of 10; while loop
echo 'r=1;for(i=1;i<=10;i++){r*=i};r' | bc -l  # Factorial of 10; for loop
echo 'define mul(x,y){return x*y}mul(2,3)' | bc # Functions there
echo '!((1&&0)||1)' | bc      # GNU bc, not POSIX bc: not, and, or (logical operations)
echo 'e(l(2)*1/3)' | bc -l    # 2 ^ 1/3; exponentiation with non-integers
bc <<< '2*17'                 # Works in bash
bc -l                         # Starts interactive use; enter quit to quit

Example session

This is an example of a user starting bc, doing two calculations, and exiting with "quit". Note that pressing ^D (control-D) also exits.

$ bc -l
3 + 4
7
2 / 5
.40000000000000000000
quit
$

Example script

Some versions of "bc" limit function and variable names to one letter. The following example has long function and variable names and must be changed to work on these copies of "bc".

The following example was tested with OpenBSD bc and has also been verified with Gnu bc version 1.06 patchlevel 2.

This script implements Simpson's rule for integration. The function "integrate" approximates the definite integral from "a" to "b" using "n" parabola sections. The formula for "simpson" is taken from the Wikipedia article. This example integrates the sine function, but different functions can be used by replacing f.

define f(x) {
  return s(x);
}

define simpson(a,b) {
  return ( (b-a)/6 ) * ( f(a) + 4*f((a+b)/2) + f(b) );
}

define integrate(a,b,n) {
  delta = (b - a) / n;
  result = 0;

  for(i = a; (n = n - 1) + 1; i = i + delta) {
    /*print "calling simpson(", i, ", ", i + delta, ") with n = ", n, "\n";*/
    result = result + simpson(i, i + delta);
  }
  return result;
}

Put this in a file, say "simpson", load it, and integrate f from 0 to pi (pi is "4*a(1)", 4 times arctangent of 1) with 100 intervals:

$ bc -l simpson
integrate(0, 4*a(1), 100)
2.00000000067647189101
^D

Explanation : Now explain these features so users can understand the script.

  • variables and statements
  • "for" loops
  • functions ("define" and "return")
  • standard library functions ("s" is sine)

Basic operations

Conversions

First check default values of base for input ( ibase) and output ( obase) numbers :

ibase
10
obase
10

Note that obase and ibase are special variables which define output and input base. Obase values range from 2 to 999 and ibase values range from 2 to 16.

Then one can convert the number 12 from base 10 to base 2:

$ echo 'obase=2;12' | bc

yielding:

1100

Limitations

  • Bc does not support floating-point arithmetic. It supports fixed-point arithmetic, and the fixed number of decimal points can be set to be rather large, via scale.
  • bc does not allow numbers to be entered in the scientific notation, like 5.031E10.