pickle broken: can't handle NaN or Infinity under win32

Tim Peters tim.peters at gmail.com
Thu Jun 23 12:01:12 EDT 2005


[Tim Peters']
>> Well, I try, Ivan.  But lest the point be missed <wink>, 754 doesn't
>> _want_ +0 and -0 to act differently in "almost any" way.  The only
>> good rationale I've seen for why it makes the distinction at all is in
>> Kahan's paper "Branch Cuts for Complex
>> Elementary Functions, or Much Ado About Nothing's Sign Bit".  There
>> are examples in that where, when working with complex numbers, you can
>> easily stumble into getting real-world dead-wrong results if there's
>> only one flavor of 0.  And, of course, atan2 exists primarily to help
>> convert complex numbers from rectangular to polar form.

[Steven D'Aprano]
> It isn't necessary to look at complex numbers to see the difference
> between positive and negative zero. Just look at a graph of y=1/x. In
> particular, look at the behaviour of the graph around x=0. Now tell me
> that the sign of zero doesn't make a difference.

OK, I looked, and it made no difference to me.  Really.  If I had an
infinitely tall monitor, maybe I could see a difference, but I don't
-- the sign of 0 on the nose makes no difference to the behavior of
1/x for any x other than 0.  On my finite monitor, I see it looks like
the line x=0 is an asymptote, and the graph approaches minus infinity
on that line from the left and positive infinity from the right; the
value of 1/0 doesn't matter to that.

> Signed zeroes also preserve 1/(1/x) == x for all x,

No, signed zeros "preverse" that identity for exactly the set {+Inf,
-Inf}, and that's all.  That's worth something, but 1/(1/x) == x isn't
generally true in 754 anyway.  Most obviously, when x is subnormal,
1/x overflows to an infinity (the 754 exponent range isn't symmetric
around 0 -- subnormals make it "heavy" on the negative side), and then
1/(1/x) is a zero, not x.  1/(1/x) == x doesn't hold for a great many
normal x either (pick a pile at random and check -- you'll find
counterexamples quickly).

> admittedly at the cost of y==x iff 1/y == 1/x (which fails for y=-0 and x=+0).
>
> Technically, -0 and +0 are not the same (for some definition of "technically"); but
> practicality beats purity and it is more useful to have -0==+0 than the alternative.

Can just repeat that the only good rationale I've seen is in Kahan's
paper (previously referenced).

>> Odd bit o' trivia:  following "the rules" for signed zeroes in 754
>> makes exponeniation c**n ambiguous, where c is a complex number with
>> c.real == c.imag == 0.0 (but the zeroes may be signed), and n is a
>> positive integer.  The signs on the zeroes coming out can depend on
>> the exact order in which multiplications are performed, because the
>> underlying multiplication isn't associative despite that it's exact.

> That's an implementation failure. Mathematically, the sign of 0**n should
> depend only on whether n is odd or even. If c**n is ambiguous, then that's
> a bug in the implementation, not the standard.

As I said, these are complex zeroes, not real zeroes.  The 754
standard doesn't say anything about complex numbers.  In rectangular
form, a complex zero contains two real zeroes.  There are 4
possiblities for a complex zero if the components are 754
floats/doubles:

    +0+0i
    +0-0i
    -0+0i
    -0-0i

Implement Cartesian complex multiplication in the obvious way:

    (a+bi)(c+di) = (ac-bd) + (ad+bc)i

Now use that to raise the four complex zeroes above to various integer
powers, trying different ways of grouping the multiplications.  For
example, x**4 can be computed as

  ((xx)x)x

or

  (xx)(xx)

or

  x((xx)x)

etc.  You'll discover that, in some cases, for fixed x and n, the
signs of the zeroes in the result depend how the multiplications were
grouped.  The 754 standard says nothing about any of this, _except_
for the results of multiplying and adding 754 zeroes.  Multiplication
of signed zeroes in 754 is associative.  The problem is that the
extension to Cartesian complex multiplication isn't associative under
these rules in some all-zero cases, mostly because the sum of two
signed zeroes is (under 3 of the rounding modes) +0 unless both
addends are -0.  Try examples and you'll discover this for yourself.

I was part of NCEG (the Numerical C Extension Group) at the time I
stumbled into this, and they didn't have any trouble following it
<wink>.  It was a surprise to everyone at the time that Cartesian
multiplication of complex zeroes lost associativity when applying 754
rules in the obvious way, and no resolution was reached at that time.

>> I stumbled into this in the 80's when KSR's Fortran compiler failed a
>> federal conformance test, precisely because the test did atan2 on the
>> components of an all-zero complex raised to an integer power, and I
>> had written one of the few 754-conforming libms at the time.  They
>> wanted 0, while my atan2 dutifully returned -pi.  I haven't had much
>> personal love for 754 esoterica since then ...

> Sounds to me that the Feds wanted something broken and you gave them
> something that was working. No wonder they failed you :-)

Yup, and they did a lot of that <0.9 wink>.  Luckily(?), Fortran is so
eager to allow optimizations that failure due to numeric differences
in conformance tests rarely withstood challenge.



More information about the Python-list mailing list