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

G

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.

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.]
 
T

Tim Peters

[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.
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 said:
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.
 
G

Grant Edwards

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


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.
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.
 
T

Tim Peters

[Tim Peters]
....
[Grant Edwards]
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>.

....
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.

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

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.
 
G

Grant Edwards

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. :)
 
G

Grant Edwards

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.
 
?

=?ISO-8859-1?Q?=22Martin_v=2E_L=F6wis=22?=

Grant said:
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
 
?

=?ISO-8859-1?Q?=22Martin_v=2E_L=F6wis=22?=

Grant said:
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
 
G

Grant Edwards

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.
 
T

Tim Peters

[Grant Edwards]
[Martin v. Löwis]
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 said:
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).

Ya, and Unicode defines 16-bit little-endian characters <wink>.
Seriously, the 754 standard is quite involved, and there's just no
visible point I can see to trotting out its elaborate details here.
If Python claimed to support 754, then details would be important.
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).
 
M

Michael Hudson

Grant Edwards said:
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
 
G

Grant Edwards

Grant Edwards said:
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.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Members online

Forum statistics

Threads
473,994
Messages
2,570,223
Members
46,812
Latest member
GracielaWa

Latest Threads

Top