The calculator rounded the result
to a smaller number of decimal digits
than the 16 provided by the underlying
arithmetic. This reduced the probability that a number with a finite decimal
expansion like 12. 34, but an infinite
binary expansion, would be displayed
as 12.399999999. But there was an unavoidable tension between not dropping enough digits and generating unpleasant representations, and dropping
too many. The latter would either introduce additional error for intermediate
results, or it would force the calculator
to display a result significantly different
from its internal representation. Both
could produce unpleasant surprises.
A Web search for “Android Calculator
bug” shows some of the results. The
nature of the complaints also confirms
that most users are not happy to tolerate the kind of floating-point issues that
a numerical analyst would expect.
Accurate Answers From a Calculator
Our goal was to replace the arithmetic
evaluation engine in the Android Calculator with one that was not subject
to floating point-rounding errors. We
wanted to ensure at a minimum that the
displayed final answer was never off by
one or more in the final displayed digit.
This can be done using “
constructive real arithmetic.”d,e Rather than
computing a fixed number of digits for
each intermediate result, each subex-pression is computed to whatever precision is needed to ensure sufficient
accuracy of the final result.
Let’s say we want to compute π+ 1/3,
and the calculator display has 10 digits.
We would compute both π and 1/3 to 11
digits each, add them, and round the
result to 10 digits. Since π and 1/3 were
accurate to within 1 in the 11th digit, and
rounding adds an error of at most 5 in
the 11th digit, the result is guaranteed
accurate to less than 1 in the 10th digit,
which was our goal.
Other operations are somewhat
more complex to implement. Multiplication to 10 digits beyond the decimal
point might involve evaluating one argument to five digits. If that is zero, we
d E. Bishop, and D. Bridges. Constructive Analysis.
Springer Science & Business Media, 1985.
e Boehm, HJ., and Cartwright, R. Exact real
arithmetic: Formulating real numbers as func-
tions. Rice University, Department of CS, 1988.
people often seem surprised when we
For numerical differentiation with
machine floating point, there is a subtle trade-off in the choice of h, which
is likely to be well beyond the expertise of a high school student trying to
check a formula on a calculator. And
yet there is no reason calculations
like this shouldn’t just work, even
with h = 10–1000. The sidebar entitled
“Derivatives on a Calculator” pushes
this example a bit further.
Our Starting Point
The Android Open Source Project has
always included a relatively simple
calculator application. This is the de-
fault calculator on Pixel phones and
many other Andriod devices. Histori-
cally some other third-party Android
calculators have also extended the
same source code base. This calcula-
tor is designed to be as simple as pos-
sible, targeting primarily nontechni-
cal users rather than engineers. It has
always offered “scientific calculator”
functionality, with trigonometric
functions, among others. But the em-
phasis has been on simple use cases
and conformance to Android user in-
In versions prior to Android 6.0
Marshmallow, the calculator internally used the “arity” expression evaluation library.c The calculator uses this
library to evaluate traditional infix
expressions. Conventional syntax is
mildly extended to allow dropping of
trailing parentheses and a few other
shortcuts. The actual evaluation is
performed using double precision
machine floating point.
c Mihai Preda, https://code.google.com/p/arity-calculator/
A Fixed-Precision Fail
Although conventional calculators usually provide plenty of precision for most
purposes, they are prone to occasional misbehavior on surprisingly simple problems.
These are more likely to be problems encountered by high school or college students
experimenting with mathematical laws, than they are real engineering problems.
One particularly small example involves the trigonometric tangent (tan) and
arctangent (tan– 1) functions. The expression tan(tan– 1(x)) maps a slope x to
the corresponding angle and back, and should clearly always give us back x. But
evaluating this expression correctly for large x tends to be quite tricky, since tan– 1 of
a large argument produces a result very close to π/2 radians (or 90 degrees), which is a
singularity for the tan function.
On software-based calculators (Android or Web), a result something like the one
shown here is common for tan(tan- 1(1020)).
On old-fashioned hardware calculators we tried, the arguably better answer shown
below is more common.
The standard Microsoft Windows calculator we tried uses more precision, and
hence fails only with even larger values of x.