Python -- floating point arithmetic
Mark Dickinson
dickinsm at gmail.com
Thu Jul 8 17:54:27 EDT 2010
On Jul 8, 9:52 pm, Wolfram Hinderer <wolfram.hinde... at googlemail.com>
wrote:
> JFTR, it works because a+b == a+b (while I don't think that a+b == b+a
> holds for all a and b).
Actually, that's one of the few identities that's safe. Well, for non-
NaN IEEE 754 floating-point, at any rate. And assuming that there's
no use of extended precision to compute intermediate results (in which
case one side could conceivably be computed with different precision
from the other; but that applies to a+b == a+b, too). And assuming
that no FPE signals occur and halt the program... (e.g., for overflow,
or from doing -inf + inf). Okay, maybe not that safe, then. :)
For NaNs, there are two problems: first, if exactly one of a and b is
a NaN then a+b and b+a will both be NaNs, so a + b == b + a will be
false, even though they're identical. Second, if a and b are *both*
NaNs, and you're feeling really fussy and care about signs and
payloads, then a + b and b + a won't even necessarily be bitwise
identical: a + b will have the sign and payload of a, while b + a has
the sign and payload of b. You can see something similar with the
Decimal module:
>>> Decimal('NaN123') + Decimal('-NaN456')
Decimal('NaN123')
>>> Decimal('-NaN456') + Decimal('NaN123')
Decimal('-NaN456')
Or more directly (just for fun), using the struct module to create
particular nans:
>>> import struct
>>> x = struct.unpack('<d', '\xff\xff\xff\xff\xff\xff\xff\xff')[0]
>>> y = struct.unpack('<d', '\xfe\xff\xff\xff\xff\xff\xff\xff')[0]
>>> x
nan
>>> y
nan
>>> struct.pack('<d', x+y) # identical to x
'\xff\xff\xff\xff\xff\xff\xff\xff'
>>> struct.pack('<d', y+x) # identical to y
'\xfe\xff\xff\xff\xff\xff\xff\xff'
Isn't floating-point a wonderful thing. :)
--
Mark
--
Mark
More information about the Python-list
mailing list