Hacker News new | past | comments | ask | show | jobs | submit login
More Intuitive Calculator Arithmetic (2018) (desmos.com)
50 points by jwmerrill on Oct 23, 2019 | hide | past | favorite | 21 comments



There's a related very nice article about the calculator in Android, by Hans-J. Boehm: https://cacm.acm.org/magazines/2017/8/219594-small-data-comp... Small-Data Computing: Correct Calculator Arithmetic


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.


This looks pretty interesting. Is there any good resource on this?


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.

[1] https://wiki.haskell.org/Exact_real_arithmetic

[2] https://members.loria.fr/PZimmermann/irram18.pdf

[3] https://android.googlesource.com/platform/packages/apps/Exac...



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

https://iquilezles.org/www/articles/floatingbar/floatingbar....


> 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.


The Windows calculator uses rationals with arbitrary precision too.


"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.


I know that in Python, you can do:

    >>> import fractions
    >>> from fractions import Fraction as F
    >>> F(3, 17) * F(12, 5) + F(56, 99)
    Fraction(8324, 8415)
    >>> F(3, 17) * F(12, 5) + F(56, 99) / 3 + 2 * 4
    Fraction(217412, 25245)
However, if you use a float or a complex with it, the fraction get resolved:

    >>> F(217412, 25245) + 0.1
    8.712081600316894
    >>> F(217412, 25245) + 1j
    (8.612081600316895+1j)
You also have some constants:

    >>> 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.

https://docs.perl6.org/language/numerics#Rational


> "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).


Yeah, they just lack exposure to systems that do:

  :; sbcl
  This is SBCL 1.5.5, an implementation of ANSI Common Lisp.
  ...
  * (/ 1 3)
  1/3


To be fair that is a pretty recent addition to Lisp, only added in the late 1970s. They might not be keeping up with the latest stuff.


tl;dr "We switched from floats to rationals."

Because we made out calculator in JavaScript.

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.


Yeah, a float isn't a number, it's a number with an error bar.


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.




Consider applying for YC's Spring batch! Applications are open till Feb 11.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: