# Math errors in python

Alex Martelli aleaxit at yahoo.com
Sun Sep 19 19:21:49 CEST 2004

```Gary Herron <gherron at islandtraining.com> wrote:
...
> > > irrational numbers like sqrt(2) and transcendental numbers like PI?
> >
> > Sqrt is a fair criticism, but Pi equals 22/7,
>
> What? WHAT?  Are you nuts?  Pi and 22/7 are most certainly not equal.
> They don't even share three digits beyond the decimal point.  (Can you
> really be that ignorant about numbers and expect to contribute
> intelligently to a discussion about numbers.  Pi is a non-repeating
> and non-ending number in base 10 or any other base.)

Any _integer_ base -- you can find infinitely many irrational bases in
which pi has repeating or terminating expansion (for example, you could
use pi itself as a base;-).  OK, OK, I _am_ being silly!-)

> If you are happy doing calculations with decimal numbers like 12.10 +
> 8.30, then the Decimal package may be what you want, but that fails as
> soon as you want 1/3.

But it fails in exactly the same way as a cheap calculator of the same
precision, and some people just have a fetish for that.

> But then you could use a rational arithmetic
> package and get 1/3, but that would fail as soon as you needed sqrt(2)
> or Pi.  But then you could try ... what?  Can you see the pattern

Uh, "constructive reals", such as those you can find at
<http://www.hpl.hp.com/personal/Hans_Boehm/crcalc/> ...?

"Numbers are represented exactly internally to the calculator, and then
evaluated on demand to guarantee an error in the displayed result that
is strictly less than one in the least significant displayed digit. It
is possible to scroll the display to the right to generate essentially
arbitrary precision in the result."  It has trig, logs, etc.

> here?  Any representation of the infinity of numbers on a finite
> computer *must* necessarily be unable to represent some (actually
> infinity many) of those numbers.  The inaccuracies stem from that
> fact.

Yes, _but_.  There is after all a *finite* set of reals you can describe
(constructively and univocally) by equations that you can write finitely
with a given finite alphabet, right?  So, infinitely many (and indeed
infinitely many MORE, since reals overall are _uncountably_ infinite;-)
reals are of no possible constructive interest -- if we were somehow
given one, we would have no way to verify that it is what it is claimed
to be, anyway, since no claim for it can be written finitely over
whatever finite alphabet we previously agreed to use.  So, I think we
can safely restrict discourse by ignoring, at least, the _uncountably_
infinite aspects of reals and sticking to some "potentially
constructively interesting" subset that is _countably_ infinite.

At this point, the theoretical problems aren't much worse than those you
meet with, say, integers, or just rationals, etc.  Sure, you can't
represent any but a finite subset of integers (or rationals, etc) in a
finite computer _in a finite time_, yet that implies no _inaccuracy_
whatsoever -- specify your finite alphabet and the maximum size of
equation you want to be able to write, and I'll give you the specs for
how big a computer I will need to serve your needs.  Easy!

A "constructive reals" library able to hold and manipulate all reals
that can be described as the sum of convergent series such that the Nth
term of the series is a ratio of polynomials in N whose tuples of
coefficients fit comfortably in memory (with space left over for some
computation), for example, would amply suffice to deal with all commonly
used 'transcendentals', such as the ones arising from trigonometry,
logarithms, etc, and many more besides.  (My memories of arithmetic are
SO rusty I don't even recall if adding similarly constrained continuous
fractions to the mix would make any substantial difference, sigh...).

If you ask for some sufficiently big computation you may happen to run
out of memory -- not different from what happens if you ask for a
raising-to-power between two Python long's which happen to be too big
for your computer's memory.  Buy more memory, move to a 64-bit CPU (and
a good OS for it), whatever: it's not a problem of _accuracy_, anyway.

It MAY be a problem of TIME -- if you're in any hurry, and have upgraded
your computer to have a few hundred terabytes of memory, you MAY be
disappointed at how deucedly long it takes to get that multiplication
between longs that just happened to overflow the memory resources of
your previous machine which had just 200 TB.  If you ask for an infinite
representation of whatever, it will take an infinite time for you to see
it, of course -- your machine will keep emitting digits at whatever
rate, even very fast, but if the digits never stop coming then you'll
never stop staring at them able to truthfully say "I've seen them ALL".
But that's an effect that's easy to get even with such a simple
computation as 1/3... it may easily be held with perfect accuracy inside
the machine, just by using rationals, but if you want to see it as a
decimal number you'll never be done.  Similarly for sqrt(2) and so on.

But again it's not a problem of _accuracy_, just one of patience;-).  If
the machine is well programmed you'll never see even one wrong digit, no
matter how long you keep staring and hoping to catch an accuracy issue.

The reason we tend to use limited accuracy more often than strictly
needed is that we typically ARE in a hurry.  E.g., I have measured the
radius of a semispherical fishbowl at 98.13 cm and want to know how much
water I need to fetch to fill it: I do NOT want to spend eons checking
out the millionth digit -- I started with a measurement that has four or
so significant digits (way more than _typical_ real-life measurements in
most cases, btw), it's obvious that I'll be satisfied with just a few
more significant digits in the answer.  In fact, Python's floats are
_just fine_ for just about any real-life computation, excluding ones
involving money (which may often be constrained by law or at least by
common practice) and some involving combinatorial arithmetic (and thus,
typically, ratios between very large integers), but the latter only
apply to certain maniacs trying to compute stuff about games (such as,
yours truly;-).

> So while a calculator will fool you into believing it is accurate when
> it is not, it is Python's design decision to not cater to fools.

Well put (+1 QOTW).  But constructive reals are still COOL, even if
they're not of much practical use in real life;-).

Alex

```