Wow, this is better than I've ever expected: Android calculator makes use of Exact Real Arithmetic running in the background (with some tweaks to cope with the inherent undecidability and an infinite list of trailing zeros). I had been fully aware of ERA but never expected to see that in a such widespread application.
Searching for "Exact Real Arithmetic" will yield some. Specifically, a HaskellWiki page [1] is not too bad as a starting point. Or, if you are keen to academic presentations (read: presentations optimized for the maximal information density and not for the actual presentation ;-) [2] might be better.
You can also take a look at the actual source code for the Android ExactCalculator app [3]. For some reason, however, it is deprecated after Android 9.0.0; don't know why.
This is super neat! Desmos is one of my favorite tools. For anyone interested in efficient rational number representation, I highly recommend the entertaining article on "floating bar" for ray-tracing algorithms by Inigo Quilez
> It took a while for us to settle on the idea of using rationals with limited-sized integers for the numerator and denominator and falling back to binary floating point when we have to. I doubt this idea is original—it’s a combination of a few well-established ideas—but I’m also not aware of any calculator (or programming language) that currently works this way.
I am fairly sure this is exactly how my calculators (a Casio fx-115ES PLUS and a TI-89) work…
I don't have any experience with Casio calculators, but my recollection of the TI-89 and HP's competitors that have computer algebra systems is that by default they won't switch your data from rationals to floats without asking or alerting you.
However, if you input a number containing a decimal point it will be represented as a floating point number and performing arithmetic between that and a rational will cause the rational to be coerced to a floating point number and yield a floating point result. (If you're working with a more complicated expression, you can sometimes end up with some terms/coefficients of the expression being rational numbers and some being floats, until you ask for the expression to be fully evaluated down to a numerical result.)
They will fall back if they cannot represent the number as a rational; I just pulled them out and had them do \sum_{x=1}^{1000}\frac{1}{x^2} and they both gave me a decimal result.
"I’m also not aware of any calculator (or programming language) that currently works this way." [represent fractions exactly wherever reasonable to do so]
This is surprising to me!
Casio scientific calculators definitely do this, and have done for many years now. And Casio (it appears) also represents pi and square roots exactly/symbolicly, wherever it's reasonable to do so.
>>> import math
>>> math.pi
3.141592653589793
>>> math.e
2.718281828459045
But they are not just symbol, there is a precision-limited value behind it. Although the value seems to match the precision NASA considers to be enough for trajectories of spacecrafts like Voyager: https://www.jpl.nasa.gov/edu/news/2016/3/16/how-many-decimal...
Raku Perl 6 uses rationals by default for decimal literals. No imports necessary. You actually have to opt-in to floating point by using engineering notation.
> "I’m also not aware of any calculator (or programming language) that currently works this way." [represent fractions exactly wherever reasonable to do so]
Author here. The paraphrase makes this sound wrong, but what I actually meant is that I don’t know of any calculator that uses rationals while the numerator and denominator can be represented as integer floating point doubles, and then falls back to a single floating point double if the numerator or denominator overflow.
I am aware of many systems that use arbitrary precision rationals, and I mentioned this in the post:
> Rational numbers where the numerator and denominator are allowed to grow arbitrarily large are used by computer algebra systems (CAS) like Mathematica and Maple (and also some high-end handheld graphing calculators).
Relatedly, lately I've been thinking of floats not as numbers but as number intervals. Their arithmetic doesn't really work that way but it's much better intuition for all the weirdness.
They switched from floats to rationals falling back to floats when the numerator or denominator gets large. And I don't see that Javascript deserves any particular praise or blame for that choice; it would be a perfectly reasonable way to implement a calculator in any language.
One awkwardness with interval arithmetic is that after twenty or thirty multiplications the error bar can get large enough to make the answer not useful.
Twenty or thirty is not a large number in many reasonable calculations, for instance with finite element calculations or Markov chanis.
This is actually a really important factor that a lot of code just ignores. Floats are decent general purpose numbers for a lot of uses but they come with a whole bunch of caveats where you can lose a lot of precision really fast.