`bc`

is a quirky but useful calculator. It is a standard Unix utility and is also available for Windows.

One nice feature of `bc`

is that you can set the parameter `scale`

to indicate the desired precision. For example, if you set `scale=100`

, all calculations will be carried out to 100 decimal places.

**The first surprise** is that the default value of `scale`

is 0. So unless you change the default option, 1/2 will return 0. This is not because it is doing integer division: 1.0/2.0 also returns 0. `bc`

is computing 1/2 as 0.5 and displaying the default number of decimal places, i.e. none! Note also that `bc`

doesn’t round results; it truncates.

`bc`

has one option: `-l`

. This option loads the math library and sets the default value of `scale`

to 20. I always fire up `bc -l`

rather than just `bc`

.

**The second surprise** with `bc`

is that its math library only has five elementary functions. However, you can do a lot with these five functions if you know a few identities.

The **sine** and **cosine** of `x`

are computed by `s(x)`

and `c(x)`

respectively. Angles are measured in radians. There is no tangent function in `bc`

. If you want the tangent of `x`

, compute `s(x)/c(x)`

. (See here for an explanation of how to compute other trigonometric functions.) As minimal as `bc`

is, it did make a minor concession to convenience: it could have been more minimal by insisting you use sin(π/2 – *x*) to compute a cosine.

The only inverse trigonometric function is `a(x)`

for **arctangent**. This function can be bootsrapped to compute other inverse functions via these identities:

The functions `l(x)`

and `e(x)`

compute (natural) **logarithm** and **exponential** respectively. `bc`

has a power operator `^`

but it can only be used for integer powers. So you could compute the fourth power of *x* with `x^4`

but you cannot compute the fourth root of *x* with `x^0.25`

. To compute *x ^{y}* for a floating point value

*y*, use

`e(l(x)*y)`

. Also, you can use the identity log*(*

_{b}*x*) = log(

*x*) / log(

*b*) to find logarithms to other bases. For example, you could compute the log base 2 of

*x*using

`l(x)/l(2)`

.Not only is `bc`

surprising for the functions it *does not* contain, such as no tangent function, it is also surprising for what it *does* contain. **The third surprise** is that in addition to its five elementary functions, the `bc`

math library has a function `j(n,x)`

to compute the *n*th Bessel function of *x* where *n* is an integer. (You can pass in a floating point value of *n* but `bc`

will lop off the fractional part.)

I don’t know the history of `bc`

, but it seems someone must have needed Bessel functions and convinced the author to add them. Without `j`

, the library consists entirely of elementary functions of one argument and the names of the functions spell out “scale.” The function `j`

breaks this pattern.

If I could include one advanced function in a calculator, it would be the gamma function, not Bessel functions. (Actually, the *logarithm* of the gamma function is more useful than the gamma function itself, as I explain here.) Bessel functions are important in applications but I would expect more demand for the gamma function.

**Update** (September 4, 2019): Published a follow up post, More bc weirdness.

bc is also great for proving that 6*9=42.

set obase=13

set ibase=10

6 * 9

42

or for proving that 1 + 1 = 10

set obase = 2

set ibase = 10

1 + 1

10

There are other integer functions that I wish were included by default, like min(), max(), … I’ve added those to my environment using:

the script

> bc is also great for proving that 6*9=42.

Somebodyknows their Douglas Adams. :-)More surprises:

-limits to ibase and obase

-using single-letter variable names

-sqrt, an exception to your variable rules and to the need for e(l(x)/2).

-basic programming syntax

Having `bc -l` follow you on Twitter would be the biggest surprise of them all!

I think you forgot the most important feature of running bc without -l option:

It does arbitrary precision integer arithmetic!

This proves that the 5th Fermat number is not a prime:

$ echo ‘(2^2^5+1)%641’ | bc -q

0

$

Also you can extend bc easily using “define” and add all the functions you want with your identities. “man bc” is worth reading.

$ cat fs.bc

define t(x) {

return s(x)/c(x);

}

pi=4*a(1);

$

$ bc -lq fs.bc

pi

3.14159265358979323844

t(0)

0

t(pi/4)

.99999999999999999998

I can’t thank you enough. I’ve been struggling with the implementation of asin, acos, acsc, asec, and acot in my bc-based rpn calculator script and your guidance has allowed me to finally sort this out. As a bonus, I’ve also been able to implement floating point exponents per your guidance, so yeah, today was a great day and I have you to thank for it. You can find the rpn calculator script on github, btw, if you’re interested in such a thing.

bc is a kind of “decimal” calculator.

Two branchs of bc program:

– gnu bc : standalone program.

– classical one: preprocessor of dc (early Unix, plan9, …): (dc does the arithmetics) (1975)

Classical bc and dc are very well documented and the code (dc.c) is pretty easy to read.

See : https://9p.io/sources/plan9/sys/src/cmd/dc.c

Great papers published by bc and dc authors Robert Morris and Lorinda Cherry of Bell Labs :

http://www.unixprogram.com/bc.pdf

https://wolfram.schneider.org/bsd/7thEdManVol2/dc/dc.pdf

One point drew my attention

Numbers are stored as “strings” of digits in base 100 with a scale value. 101.01 is the number 1 01 01 with a scale of 2. Then addition, substraction, multiplication and division are made the same way we do on a sheet of paper with the concept of carry. The program never use “floating point arithmetic” of the processor. The processor only manipulates integers for 0 to 99.

Truncation rules are applied. See : https://plan9.io/magic/man2html/1/dc

NB : scale factor does not guarantee the accuracy of results. Writing math functions with bc must be done with extreme care to scales.

Other tool: Hoc “high oder calculator” is a 64bits floatting point arithmetics simple language with a syntax close to bc.

See: https://plan9.io/magic/man2html/1/hoc

(available on plan9port for macosX, linux, unix and on 9pm for windows 10.)

See : https://9fans.github.io/plan9port/