f



Why does python break IEEE 754 for 1.0/0.0 and 0.0/0.0?

I've read over and over that Python leaves floating point
issues up to the underlying platform.  

This seems to be largely true, but not always.  My underlying
platform (IA32 Linux) correctly handles 1.0/0.0 and 0.0/0.0
according to the IEEE 754 standard, but Python goes out of its
way to do the wrong thing.

1/0 is defined by the standard as +Inf and 0/0 is NaN.

That's what my platform does for programs written in C.  Python
apparently checks for division by zero and throws and exception
rather than returning the correct value calculated by the
underlying platform.

Is there any way to get Python to return the correct results
for those operations rather than raising an exception?

There's no way to "resume" from the exception and return a 
value from an exception handler, right?  [This is the other
option allowed by the IEEE 754 standard.]

-- 
Grant Edwards                   grante             Yow!  ... I want a COLOR
                                  at               T.V. and a VIBRATING BED!!!
                               visi.com            
0
grante (5416)
7/14/2005 6:44:46 PM
comp.lang.python 77058 articles. 6 followers. Post Follow

11 Replies
1651 Views

Similar Articles

[PageSpeed] 48

[Grant Edwards]
> I've read over and over that Python leaves floating point
> issues up to the underlying platform.
>
> This seems to be largely true, but not always.  My underlying
> platform (IA32 Linux) correctly handles 1.0/0.0 and 0.0/0.0
> according to the IEEE 754 standard, but Python goes out of its
> way to do the wrong thing.

Python does go out of its way to raise ZeroDivisionError when dividing by 0=
..

> 1/0 is defined by the standard as +Inf and 0/0 is NaN.
>
> That's what my platform does for programs written in C.

IOW, that's what your platform C does (the behavior of these cases is
left undefined by the C89 standard, so it's not the case that you can
write a _portable_ C89 program relying on these outcomes).  What does
your platform C return for the integer expression 42/0?  Is any other
outcome "wrong"?

> Python apparently checks for division by zero and throws and exception
> rather than returning the correct value calculated by the
> underlying platform.
>
> Is there any way to get Python to return the correct results
> for those operations rather than raising an exception?

No, except when using the decimal module.  The latter provides all the
facilities in IBM's proposed standard for decimal floating-point,
which intends to be a superset of IEEE 854:

    http://www2.hursley.ibm.com/decimal/

It's relatively easy to do this in the decimal module because it
emulates, in software, all the gimmicks that most modern FPUs provide
in hardware.

Note that support for 754 was rare on Python platforms at the time
Python was designed, and nobody mentioned 754 support as even a vague
desire in those days.  In the absence of user interest, and in the
absence of HW support for NaNs or infinities on most Python platforms,
the decision to raise an exception was quite sensible at the time.=20
Python could not have implemented 754 semantics without doing
emulating fp arithmetic in SW on most platforms (as the decimal module
does today), and for much the same reasons you can't give a non-silly
answer to my earlier "what does your platform C return for the integer
expression 42/0?" question today <wink>.

> There's no way to "resume" from the exception and return a
> value from an exception handler, right?

Correct.

Note that there's a huge, current, informed discussion of these issues
already in the math.nroot thread.
0
tim.peters (499)
7/14/2005 7:14:26 PM
On 2005-07-14, Tim Peters <tim.peters@gmail.com> wrote:

> Python does go out of its way to raise ZeroDivisionError when
> dividing by 0.
>
>> 1/0 is defined by the standard as +Inf and 0/0 is NaN.
>>
>> That's what my platform does for programs written in C.
>
> IOW, that's what your platform C does (the behavior of these
> cases is left undefined by the C89 standard, so it's not the
> case that you can write a _portable_ C89 program relying on
> these outcomes).

True, but as a paracial matter, all of the C platforms I care
about all do obey IEEE 754.

> What does your platform C return for the integer expression
> 42/0?  Is any other outcome "wrong"?

I guess I though it was obvious from my reference to IEEE 754
that I was referring to floating point operations.  I don't
know (or generally care) what my C platform does for integer
divide by zero.

>> Python apparently checks for division by zero and throws and
>> exception rather than returning the correct value calculated
>> by the underlying platform.
>>
>> Is there any way to get Python to return the correct results
>> for those operations rather than raising an exception?
>
> No, except when using the decimal module.  The latter provides
> all the facilities in IBM's proposed standard for decimal
> floating-point, which intends to be a superset of IEEE 854:
>
>     http://www2.hursley.ibm.com/decimal/
>
> It's relatively easy to do this in the decimal module because
> it emulates, in software, all the gimmicks that most modern
> FPUs provide in hardware.
>
> Note that support for 754 was rare on Python platforms at the
> time Python was designed, and nobody mentioned 754 support as
> even a vague desire in those days.

I often foget how old Python is.  Still, I've been using IEEE
floating point in C programs (and depending on the proper
production and handling of infinities and NaNs) for more than
20 years now.  I had thought that Python might have caught up.

> In the absence of user interest, and in the absence of HW
> support for NaNs or infinities on most Python platforms,

Really?  I would have guessed that most Python platforms are
'586 or better IA32 machines running either Windows or Linux.
They all have HW support for NaNs and Infinities.

> the decision to raise an exception was quite sensible at the
> time. Python could not have implemented 754 semantics without
> doing emulating fp arithmetic in SW on most platforms (as the
> decimal module does today), and for much the same reasons you
> can't give a non-silly answer to my earlier "what does your
> platform C return for the integer expression 42/0?" question
> today <wink>.
>
>> There's no way to "resume" from the exception and return a
>> value from an exception handler, right?
>
> Correct.
>
> Note that there's a huge, current, informed discussion of
> these issues already in the math.nroot thread.

-- 
Grant Edwards                   grante             Yow!  It's OKAY --- I'm an
                                  at               INTELLECTUAL, too.
                               visi.com            
0
grante (5416)
7/14/2005 7:33:48 PM
[Tim Peters]
....
>> What does your platform C return for the integer expression
>> 42/0?  Is any other outcome "wrong"?

[Grant Edwards]=20
> I guess I though it was obvious from my reference to IEEE 754
> that I was referring to floating point operations.

Yes, that was obvious.  Since I thought my point would be equally
obvious, I won't spell it out <0.7 wink>.

....

>> Note that support for 754 was rare on Python platforms at the
>> time Python was designed, and nobody mentioned 754 support as
>> even a vague desire in those days.

> I often foget how old Python is.  Still, I've been using IEEE
> floating point in C programs (and depending on the proper
> production and handling of infinities and NaNs) for more than
> 20 years now.  I had thought that Python might have caught up.

It has not.  Please see the other thread I mentioned.

>> In the absence of user interest, and in the absence of HW
>> support for NaNs or infinities on most Python platforms,

> Really?

Yes, but looks like you didn't finish reading the sentence.  Here's
the rest, with emphasis added:

>> the decision to raise an exception was quite sensible AT THE TIME.

You may have forgotten how much richer the "plausible HW" landscape
was at the time too.  I was deeply involved in implementing Kendall
Square Research's HW and SW 754 story at the time, and it was all
quite novel, with little prior art to draw on to help resolve the
myriad language issues 754 didn't address (e.g., what should Fortran's
3-branch Arithmetic IF statement do if fed a NaN?  there were hundreds
of headaches like that, and no cooperation among compiler vendors
since the language standards ignored 754).  The C standards didn't
mention 754 until C99, and then left all support optional (up to the
compiler implementer whether to do it).  That didn't help much for a
bigger reason:  major C vendors (like Microsoft and Borland) are still
ignoring C99.  "Subset" HW implementations of 754 were also common,
like some that didn't support denorms at all, others that didn't
implement the non-default rounding modes, some that ignored signed
zeroes, and several that implemented 754 endcases by generating kernel
traps to deal with infinities and NaNs, making them so much slower
than normal cases that users avoided them like death.

If I had to bet at the time, I would have put my money on 754 dying
out due to near-universal lack of language support, and incompatible
HW implementations.  Most programming languages still have no sane 754
story, but the remarkable dominance of the Pentium architecture
changed everything on the HW side.

>  I would have guessed that most Python platforms are
> '586 or better IA32 machines running either Windows or Linux.

Today, yes, although there are still Python users on many other OSes
and architectures.  Most of the latter support 754 too now.

> They all have HW support for NaNs and Infinities.

Yes, Intel-based boxes certainly do (and have for a long time), and so
do most others now.
0
tim.peters (499)
7/14/2005 8:20:04 PM
On 2005-07-14, Tim Peters <tim.peters@gmail.com> wrote:

> You may have forgotten how much richer the "plausible HW" landscape
> was at the time too.

I've probably blocked most of it out intentionally.  I seem to
have vague, repressed, memories of working on a Sperry machine
that used base 4 floating point.  And of course there was the
VAX.

> If I had to bet at the time, I would have put my money on 754
> dying out due to near-universal lack of language support, and
> incompatible HW implementations.  Most programming languages
> still have no sane 754 story, but the remarkable dominance of
> the Pentium architecture changed everything on the HW side.

As messed up as I think the IA32 architecture is, I do think
Intel got FP mostly right. :)

-- 
Grant Edwards                   grante             Yow!  If I felt any more
                                  at               SOPHISTICATED I would DIE
                               visi.com            of EMBARRASSMENT!
0
grante (5416)
7/14/2005 9:00:26 PM
On 2005-07-14, Grant Edwards <grante@visi.com> wrote:
> On 2005-07-14, Tim Peters <tim.peters@gmail.com> wrote:
>
>> You may have forgotten how much richer the "plausible HW" landscape
>> was at the time too.
>
> I've probably blocked most of it out intentionally.  I seem to
> have vague, repressed, memories of working on a Sperry machine
> that used base 4 floating point.

No, on second thought, I think it was base-16.

-- 
Grant Edwards                   grante             Yow!  Yow! I want my nose
                                  at               in lights!
                               visi.com            
0
grante (5416)
7/14/2005 9:09:44 PM
Grant Edwards wrote:
> I often foget how old Python is.  Still, I've been using IEEE
> floating point in C programs (and depending on the proper
> production and handling of infinities and NaNs) for more than
> 20 years now.  I had thought that Python might have caught up.

As should be clear by now, it hasn't. What made you think it would
have?

As Tim says, there are very strong reasons why Python *doesn't*
support IEEE 754, the primary one being lack of contributors that
improve it. I, for example, care much more about integer arithmetic
than floating point.

Regards,
Martin
0
ISO
7/14/2005 9:44:38 PM
Grant Edwards wrote:
> 1/0 is defined by the standard as +Inf and 0/0 is NaN.

I wonder why Tim hasn't protested here: I thought this was *not*
the case. I thought IEEE 754 defined +Inf and NaN as only a possible
outcome of these operations with other possible outcomes being
exceptions... In that case, Python would comply to IEEE 754 in this
respect (although in a different way than the C implementation on
the same system).

Regards,
Martin
0
ISO
7/14/2005 9:47:37 PM
On 2005-07-14, Martin v. L�wis <martin@v.loewis.de> wrote:

>> 1/0 is defined by the standard as +Inf and 0/0 is NaN.
>
> I wonder why Tim hasn't protested here: I thought this was *not*
> the case. I thought IEEE 754 defined +Inf and NaN as only a possible
> outcome of these operations with other possible outcomes being
> exceptions...

The "exceptions" specified by the standard aren't required, but
it's "strongly recommended" that they be provided as options
for the programmer.  If provided, I believe they are to be
resumable so that the user can determine what operation was
attempted on what operands and return a result if desired.

> In that case, Python would comply to IEEE 754 in this respect

My recollection is that returning Inf and NaN is to be the
default behavior, and a resumable exception is a recommended
option.

> (although in a different way than the C implementation on the
> same system).

I can't find my copy of the standard at the moment, though I
did just re-read Goldberg's 1991 discussion of the standard.

-- 
Grant Edwards                   grante             Yow!  My Aunt MAUREEN was
                                  at               a military advisor to IKE &
                               visi.com            TINA TURNER!!
0
grante (5416)
7/14/2005 10:09:19 PM
[Grant Edwards]
>> 1/0 is defined by the standard as +Inf and 0/0 is NaN.
=20
[Martin v. L=F6wis]
> I wonder why Tim hasn't protested here:

Partly because this thread (unlike the other current thread on the
topic) isn't moving toward making progress, and I have little time for
this.

But mostly because Python's fp design was in no way informed by 754,
so logic-chopping on the 754 standard wrt what Python actually does is
plainly perverse <0.5 wink>.

> I thought this was *not* the case. I thought IEEE 754 defined +Inf and Na=
N
> as only a possible outcome of these operations with other possible
> outcomes being exceptions... In that case, Python would comply to IEEE
> 754 in this respect (although in a different way than the C implementatio=
n on
> the same system).

Ya, and Unicode defines 16-bit little-endian characters <wink>.=20
Seriously, the 754 standard is quite involved, and there's just no
visible point I can see to trotting out its elaborate details here.=20
If Python claimed to support 754, then details would be important.=20
Short course wrt this specific point:  there's no reasonable way in
which Python's float arithmetic can be said to comply to IEEE 754 in
this case, neither in letter nor spirit.  The decimal module does,
though (mutatis mutandis wrt base).
0
tim.peters (499)
7/15/2005 12:31:57 AM
Grant Edwards <grante@visi.com> writes:

> I've read over and over that Python leaves floating point
> issues up to the underlying platform.  

Please read the conversation Tim and I are having in the "Re:
math.nroot [was Re: A brief question.]" elsewhere in this same
newsgroup.

Cheers,
mwh

-- 
  "Also, does the simple algorithm you used in Cyclops have a name?"
  "Not officially, but it answers to "hey, dumb-ass!"
                       -- Neil Schemenauer and Tim Peters, 23 Feb 2001
0
mwh (704)
7/15/2005 9:14:25 AM
On 2005-07-15, Michael Hudson <mwh@python.net> wrote:
> Grant Edwards <grante@visi.com> writes:
>
>> I've read over and over that Python leaves floating point
>> issues up to the underlying platform.  
>
> Please read the conversation Tim and I are having in the "Re:
> math.nroot [was Re: A brief question.]" elsewhere in this same
> newsgroup.

Thanks, I just found it.

-- 
Grant Edwards                   grante             Yow!  I Know A Joke!!
                                  at               
                               visi.com            
0
grante (5416)
7/15/2005 1:18:26 PM
Reply: