I wanted to stress test the bc
calculator a little and so I calculated π to 10,000 digits a couple different ways.
First I ran
time bc -l <<< "scale=10000;4*a(1)"
which calculates π as 4 arctan(1). This took 2 minutes and 38 seconds.
I imagine bc
is using some sort of power series to compute arctan, and so smaller arguments should converge faster. So next I used a formula due to John Machin (1680–1752).
time bc -l <<< "scale=10000;16*a(1/5) - 4*a(1/239)"
This took 52 seconds.
Both results were correct to 9,998 decimal places.
When you set the scale
variable to n, bc
doesn’t just carry calculations out to n decimal places; it uses more and tries to deliver n correct decimal places in the final result.
Why bc
This quirky little calculator is growing on me. For one thing, I like its limitations. If I need to do something that isn’t easy to do with bc, that probably means that I should write a script rather than trying to work directly at the command line.
Another thing I like about it is that it launches instantly. It doesn’t give you a command prompt, and so if you launch it in quiet mode you could think that it’s still loading when in fact it’s waiting on you. And if you send bc
code with a here-string as in the examples above, you don’t even have to launch it per se.
If you want to try bc
, I’d recommend launching it with the options -lq
. You might even want to alias bc
to bc -lq
. The -l
option loads math libraries. You’d think that would be the default for a calculator, but bc
was written in a more resource-constrained time when you didn’t load much by default. The -l
option also sets scale
to 20, i.e. you get twenty decimal places of precision; the default is zero!
The -q
option isn’t necessary, but it starts bc
in quiet mode, suppressing three lines of copyright and warranty announcements.
As part of its minimalist design, bc
only includes a few math functions, and you have to bootstrap the rest. For example, it includes sine and cosine but not tangent. More on how to use the built-in functions to compute more functions here.
Meh. bc is for folks who can’t handle the raw RPN awesomeness of dc.
Refs:
https://en.wikipedia.org/wiki/Bc_(programming_language)
https://en.wikipedia.org/wiki/Dc_(computer_program)
https://www.gnu.org/software/bc/
https://www.gnu.org/software/bc/manual/dc-1.05/dc.html
GNU bc obeys environment variables. Instead of aliasing it, export BC_ENV_ARGS=-lq in your .profile script.
(Sans serif faces suck. That’s the letter ell after the hyphen.)
Using environment variables to control command behavior causes problems for scripts, so in general GNU is trying to deprecate that technique.
Most scripts using bc probably don’t expect that they might get non-default behavior from an inherited environment variable. If you are aware of this danger you can protect against it by emptying or unsetting the variable in any script that uses bc, but imagine having to do this for every environment variable that might alter the behavior of any command in the script. Aliases don’t have this problem since scripts don’t (normally) expand them.
It’s pretty hard to imagine a script that wants to see copyright details from bc.
But the better solution for scripts might be to use dc, which even in GNU seems not seem to spew copyright BS unprovoked.
By the way: fascinating detour into /bin/dc :
https://news.ycombinator.com/item?id=21401365
Including a dc script that does pi to 10k digits in 2.6s on my machine.
I know it is not bc, but you should take a look at Python’s mpmath library. It is very fast. Faster than bc.
https://fredrikj.net/blog/2011/03/100-mpmath-one-liners-for-pi/