This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: float issue for NaN type in .pyc file
Type: Stage:
Components: Interpreter Core Versions:
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: mwh Nosy List: dileep_nirala, jepler, mwh, tim.peters
Priority: normal Keywords:

Created on 2004-12-07 06:24 by dileep_nirala, last changed 2022-04-11 14:56 by admin. This issue is now closed.

Messages (9)
msg23558 - (view) Author: Dileep Nirala (dileep_nirala) Date: 2004-12-07 06:24
There is a difference in output between .pyc and .py 
file, while dealing with NaN float. In fact I am doing 
a float range validation as part of my requirement. 

The content of my sample program
[test.py]
aboveMax = 1.8e+308
belowMin = -1.8e+308
print aboveMax, belowMin

While execution:
command: python test.py
output: 1.#INF -1.#INF
This output is expected and good, however if I use 
compiled python file as below,

command: python test.pyc
output: 1.0 -1.0 
This output is wrong, it does not show Nan floating 
point. 
msg23559 - (view) Author: Tim Peters (tim.peters) * (Python committer) Date: 2004-12-07 07:51
Logged In: YES 
user_id=31435

Python guarantees nothing about behavior in the 
presence of NaNs, infinities, or signed zeroes.  Anything 
you see then is a platform-dependent accident.

This should be closed with a reference to PEP 42 (I don't 
have time to look it all up now -- "non-accidental" IEEE 
behavior is a longstanding feature request, but one 
unlikely to be resolved in the foreseeable future; the 
particular problem here is that the marshal format deals 
in accidental ways with infinities, NaNs, and signed 
zeroes, so accidents in .py files may not be reproduced 
from .pyc files)
msg23560 - (view) Author: Dileep Nirala (dileep_nirala) Date: 2004-12-07 13:54
Logged In: YES 
user_id=1173293

My test cases passes for the first time but fails second 
times onward since .pyc gets loaded since it's existing.
msg23561 - (view) Author: Michael Hudson (mwh) (Python committer) Date: 2004-12-07 14:51
Logged In: YES 
user_id=6656

I know first hand how much of a pain this issue can be.

However it's not clear what can be done about it.  My vote
would go towards complaining at compile time that the
literals cannot be represented as a regular double, but even
that isn't the easiest thing to do portably!
msg23562 - (view) Author: Tim Peters (tim.peters) * (Python committer) Date: 2004-12-07 17:13
Logged In: YES 
user_id=31435

dileep_nirala:  Yes, I understood the problem.  That 
your test passed the first time was an accident.  That 
your test failed the second time was also an accident.  
Nothing is defined about what happens in Python in the 
presence of NaNs.  The most likely accident is that no 
spelling of an infinity, NaN, or negative 0.0 will survive 
when loaded from a .pyc file.  That the 
literal "1.8e+308" gave you an infinity to begin with was 
also a platform-dependent accident.  Python has no 
support for these things.  Whatever support may 
*appear* to exist derives from more-or-less random 
behaviors dervied from the platform C compiler and 
runtime libraries.  That won't be fixed unless someone 
unexpectedly volunteers a lot of new work in this area.
msg23563 - (view) Author: Tim Peters (tim.peters) * (Python committer) Date: 2004-12-07 17:33
Logged In: YES 
user_id=31435

BTW, while nothing is guaranteed here, your best shot 
at working (albeit still by accident) portable code is to 
use expressions that don't tickle IEEE special values 
directly.  For example, use

pinf = 1e300 * 1e300
minf = -pinf
nan = pinf - pinf

That will work the same way from .py or .pyc.  Whether 
pinf is actually +Infinity and nan is actually a NaN then 
remain platform-dependent accidents, but they will be 
on the majority platforms (Linux and Windows, using gcc 
or MSVC to compile Python).
msg23564 - (view) Author: Jeff Epler (jepler) Date: 2004-12-19 03:10
Logged In: YES 
user_id=2772

If this is all accidental behavior, maybe something
(marshal?  the compiler?) could issue a warning when a
special value is parsed, or marshal.dump()'d.

Imagining something like:
>>> 2e308
<stdin>:1: OverflowWarning: behavior of special
floating-point value undefined.
inf

Or else:
>>> marshal.dumps(2e308)
<stdin>:1: RuntimeWarning: marshal of special floating-point
value undefined.
's\x05\x00\x00\x002e308'
msg23565 - (view) Author: Michael Hudson (mwh) (Python committer) Date: 2004-12-19 16:35
Logged In: YES 
user_id=6656

And, er, how do you do that?

AFAIK, isnan is in SUS and C99 and recommended by IEEE-754 but isn't 
in plain old ANSI C... I also suspect that it's supported by all platforms 
we care about that, but certainly wouldn't swear to it.

OTOH, pyport.h seems to have a Py_IS_NAN macro already.  Maybe that 
would work, at least enough of the time to be useful...
msg23566 - (view) Author: Michael Hudson (mwh) (Python committer) Date: 2005-06-15 11:42
Logged In: YES 
user_id=6656

This issue should finally be dead in Python CVS HEAD.
History
Date User Action Args
2022-04-11 14:56:08adminsetgithub: 41289
2004-12-07 06:24:57dileep_niralacreate