.. title: Calculators
.. slug: calculators
.. date: 2019-04-22 16:03:35 UTC
.. tags: mathematics
.. category:
.. link:
.. description:
.. type: text
For quick calculations, I prefer to use my `HP handheld calculators whenever possible `_, simply because I'm much faster with them than with anything else thanks their responsive physical keypad and, of course, RPN. Alas, there are computational tasks that few, if any, handhelds are up to. Big numbers, in particular, usually result in an overflow rather than in the desired solution. Let's take `factorials `_ as example – they are `faster growing `_ than any ordinary functions (including exponential ones) and are thus perfectly suited for getting big numbers.
Here's how the factorial :math:`n!` looks in comparison to its little sister, the exponential :math:`e^n`:
.. image:: ../images/factorial.svg
:width: 500
:align: center
The dashed line shows the `Stirling approximation `_ :math:`\sqrt{2 \pi n} \left(\frac{n}{e}\right)^n`, which reveals that the factorial essentially grows with :math:`n^n` and thus faster than any exponential whatever its base.
Now, the largest factorial my HP42s can handle is 253!, which amounts to 5.173460992e+499. For a handheld, this is more than respectable: the largest factorial one can compute on a Linux desktop with, for example, xcalc as the calculator application, is 170!, limited simply by the fact that numbers in xcalc are represented by `double precision floats `_.
All right, xcalc is ancient. But as a matter of fact, most calculator applications running on Windows, MacOS, or Linux have `difficulties `_ with large numbers. The Windows calculator, for example, gives up at any numbers bigger than 1e+10,000, and hence can't calculate factorials larger than 3249!. And we didn't even talk about getting *exact* results, which demand `arbitrary precision arithmetic `_ already for much smaller numbers.
Let's have a look at some calculators for Linux that can do better than those above. I use `Mathematica 11.2 `_ as reference:
- 1,000,000! = 8.263932e+5,565,708, taking 1.1/0.2 s for an exact result/numerical approximation
- 100,000,000! = 1.617204e+756,570,556, taking 344/46 s for an exact result/numerical approximation
- 0verflows at $MaxNumber 1.605216761933662e+1,355,718,576,299,609
Note that a file storing the result of 100,000,000! has an uncompressed size of 0.757 GB. So be careful when writing even larger factorials to disk 😉 ($MaxNumber would be 1.35 PB!).
CLI Calculators
_______________
bc/dc
"""""
*The* `Unix calculators `_. Offer arbitrary precision since 1970, and now you know what the 'bc' stands for in this blog's title! 😉 Neither of them supports factorials out of the box, but hey, these are programming languages, not plain calculators. Examples for scripts computing factorials can be found on `Rosettacode `_ and on `Stackoverflow, `_ but be aware that these examples are horribly inefficient — for fast algorithms see `Peter Luschny's page `_. Here's the “script” for dc:
::
dc -e '?[q]sQ[d1=Qd1-lFx*]dsFxp'
After typing a number like 1000, we get an exact result. Overflows somewhat below 67,000!. bc does not, but it's too slow to be of much use for very much larger numbers.
`wcalc `_
"""""""""""""""""""""""""""""""""""""""""
Approximate results with principally arbitrary precision defined by the command line parameter P (which accepts only integers and is thus useless for really large numbers).
::
wcalc -P 10 'fact(1000000)'
Takes 1.42 s, overflows somewhat below 44,500,000!
`calc `_
""""""""""""""""""""""""""""""""""""""
My default calculator on PCs. Gives exact results.
::
calc 1000000!
Takes 330 s, and overflows somewhat below 2,200,000,000!
`hypercalc `_
""""""""""""""""""""""""""""""""""""""""""""""""""""""
When firing up hypercalc, we are greeted with ”Go ahead -- just TRY to make me overflow!”. And indeed, that's not an easy task at first. Hypercalc gives approximate results only, but essentially instantaneous ones even for absolutely monstrous numbers. The factorials we have considered so far are kids play for this program. Instead of the factorial of a million, a billion, a trillion, why not ask for the factorial of a `Googol `_! Hypercalc tells us this number amounts to 1e+(9.9565705518098e+101), and that agrees with the solution from Wolfram Alpha (see below), the only tool, which can at least partly follow hypercalc into the realm of big numbers.
But not when it comes to really big ones. Let's have a look, for example, at `Pickover's superfactorial n$ `_. What about, say, 10$? That's completely out of reach for any program I know, but not for hypercalc: 8pt8e+23804068 (PT stands for `PowerTower `_). But even this is still a very very very small number: hypercalc overflows only at 1e+308pt1e+34 or, equivalently in `Donald Knuth's up-arrow notation `_, 10↑↑1.7976e+308.
All of this is contained in a Perl script available for `download `_ (or for installation in the `AUR `_ for Archlinux users), and additionally in a `Javascript powered web interface `_.
iPython
"""""""
So far, we haven't been able to get exact results faster than with Mathematica. Let's see how python is doing in this regard. There are two possibilities, the first using plain `python `_, the second `scipy `_:
::
In [1]: import math
In [2]: %timeit math.factorial(1000000)
6.5 s ± 19.4 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
In [3]: from scipy.special import factorial
In [4]: %timeit factorial(1000000, exact=True)
6.53 s ± 17.9 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
It's disappointing that scipy doesn't outperform regular python, but instead seems to use exactly the same code. A special function should, IMHO, perform better than Mathematica (which needs only 1 s for the same task).
You can use python also directly from the terminal, and write the result to disk instead of displaying it directly:
::
echo 1000000 | python -c 'import sys; import math; print(math.factorial(int(sys.stdin.readline())))' > fac1M.dat
julia
"""""
Python turned out to be a disappointment, what about Julia, which is advertised to be suitable for `high-performance numerical analysis and computational science? `_
::
julia> @time factorial(big(1000000));
0.162650 seconds (1.57 k allocations: 53.524 MiB, 2.00% gc time)
julia> @time factorial(big(100000000));
45.550577 seconds (432.60 k allocations: 11.586 GiB, 0.90% gc time)
Now we're talking!
You can write the results to disk in this way:
::
julia> using DelimitedFiles
julia> fac1M=factorial(big(1000000));
julia> writedlm("fac1M.dat", fac1M)
Graphical calculators
_____________________
Most desktop calculators still attempt to imitate the look of handhelds, just like media players used to resemble `stereo decks `_. Some of these reconstructions are `historically accurate and appeal to our nostalgia `_, but in terms of usability, these relicts of the 1990s are among the most clumsy and inefficient user interfaces ever invented, particularly since people never use the keyboard to interact with these abominations, but the mouse. However, some graphical calculators give you the choice.
`qalculate! `_
""""""""""""""""""""""""""""""""""""""""""""
A great general purpose calculator packed with features. Includes an RPN mode and a plotting interface to gnuplot, as well as excellent conversion utilities that can be updated daily (important for currencies). We can get an approximate result for 1,000,000! in under 1 s, but 100,000,000! takes so long that I didn't wait. Overflows reportedly at 922,337,203,854,775,808!, which is impressive, but of little use because of the comparably poor performance.
`speedcrunch `_
"""""""""""""""""""""""""""""""""""""""""
Easy to use and insanely fast. Even on slow hardware, the result is there as soon as you type it. Overflows at 72,306,961!
Web calculators
_______________
Young people tell me that installing local apps is so 1990ish, and of course, you can perform essentially all calculations you ever need in the interwebs.
Casio
"""""
When I look at my colleagues desks at the office, I frequently see Casio calculators from the 1980s. Even I have `one `_, although I have no idea when and where I've acquired it (and I also don't remember ever using it). In any case, true to their roots, Casio offers a quite capable `online calculator `_. It gives 1,000,000! in about 2 s and overflows only at 1e+100,000,000, just below 14,845,000!
Wolfram Alpha
"""""""""""""
More than a calculator: a knowledge engine. You may ask what's the `weather in Berlin `_ today, and get the interesting bit of information that on April 22nd, it was -4°C in 1997 and 31°C in 1968. But foremost, Wolfram Alpha is an `arbitrary precision calculator. `_ It gives exact results where appropriate (for reasonably sized outputs) and approximate ones when the output seems to large. Regardless the task, the answers take a few second, whether you calculate 2+2 or 1e+(9^9^9)! [1e+1e+(1.58274e+369693108)]. Overflows at (2e+1573347107)! or 1e+(1e+9.196824545990035)! That's much higher than Mathematica, but still nothing compared to hypercalc.