Floating Point Accuracy Question

26 views
Skip to first unread message

Chris Winter

unread,
Feb 19, 2018, 5:53:43 PM2/19/18
to mpm...@googlegroups.com
Hello,

I was wondering if someone could explain to me why the results of these calculations are different:

from mpmath import *
mp.dps = 100

mpf(425.36) / mpf(69)
mpf('6.16463768115942048757131197962208070616791213768115942028985507246376811594202898550724637681159420289')

mpf(425.36) / mpf('69')
mpf('6.16463768115942048757131197962208070616791213768115942028985507246376811594202898550724637681159420289')

mpf('425.36') / mpf(69)
mpf('6.164637681159420289855072463768115942028985507246376811594202898550724637681159420289855072463768115926')

mpf('425.36') / mpf('69')
mpf('6.164637681159420289855072463768115942028985507246376811594202898550724637681159420289855072463768115926')

The result in the first two calculations are the same, but differ from the results of the second two calculations at the 16th decimal place onwards.

I'm using mpmath 1.0 with python 3.6.4.

Thanks,

Chris

Aaron Meurer

unread,
Feb 19, 2018, 6:06:08 PM2/19/18
to mpm...@googlegroups.com
You've discovered what is a general rule of thumb for mpmath: always
create floats with string values. For ints it doesn't matter because
Python can represent ints exactly, though it doesn't hurt either.

You can see what is going on if you look at the mpf values:

>>> mpmath.mpf(425.36)
mpf('425.3600000000000136424205265939235687255859375')
>>> mpmath.mpf('425.36')
mpf('425.3599999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999997')

mpmath.mpf('425.36') creates the 100 digit floating point number that
is closest to 425.36 exactly (basically, the closest 100 digit
floating point approximation to 10634/25). In other words,
425.3600000000...000, with enough 0's at the end to get 100 digits
(the above has 9's because the number 425.36000...0000 with 100 digits
cannot be represented as a base 2 mpf exactly).

mpf(425.36) on the other hand creates the closest floating point
approximation to the machine floating point number generated by
425.36. Roughly speaking, this is 425.360000000000 (15 digits). This
also cannot be represented exactly as a base-2 float, so after those
15 digits you get digits that are not 0.

It may help here to have an understanding of how mpmath represents
numbers http://mpmath.org/doc/current/technical.html#representation-of-numbers.
If you understand how machine floats are represented, it's more or
less the same thing (base*2^exp) except mpmath has no limits the size
of the base, and the range of the exponent (the precision) can be any
preassigned value. For a machine double the exp range is +/- 53, for
mpmath with mp.dps = 100, the range is +/- 336 (mp.prec) (again, I'm
skipping over many details, but the basic idea will help you
understand what is going on in situations like these).

Aaron Meurer
> --
> You received this message because you are subscribed to the Google Groups "mpmath" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to mpmath+un...@googlegroups.com.
> To post to this group, send email to mpm...@googlegroups.com.
> Visit this group at https://groups.google.com/group/mpmath.
> For more options, visit https://groups.google.com/d/optout.
Reply all
Reply to author
Forward
0 new messages