classification
Title: test_pickle fails on AIX -- 6.9999999999999994e-308 != 6.9999999999999984e-308
Type: behavior Stage:
Components: Tests Versions: Python 2.6
process
Status: closed Resolution: wont fix
Dependencies: Superseder:
Assigned To: mark.dickinson Nosy List: mark.dickinson, srid
Priority: normal Keywords:

Created on 2009-08-05 01:42 by srid, last changed 2009-08-14 17:14 by mark.dickinson. This issue is now closed.

Messages (5)
msg91292 - (view) Author: Sridhar Ratnakumar (srid) Date: 2009-08-05 01:42
test test_pickle failed -- errors occurred; run in verbose mode for 
details
test_pickletools
test test_pickletools failed -- Traceback (most recent call last):
  File "/home/apy/rrun/tmp/autotest/apy/lib/python2.6/test/
pickletester.py", line 546, in test_float
    self.assertEqual(value, got)
AssertionError: 6.9999999999999994e-308 != 6.9999999999999984e-308
msg91351 - (view) Author: Mark Dickinson (mark.dickinson) * (Python committer) Date: 2009-08-06 09:39
Thanks for the report!

What's the underlying hardware on your machine?

Here's a Python 2.6 interpreter session on my machine (OS X 10.5/Intel).  
Would it be possible for you to execute the same commands on your machine 
and tell me what you get?

Python 2.6.2 (r262:71600, Jun 17 2009, 09:08:27) 
[GCC 4.0.1 (Apple Inc. build 5490)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from sys import float_info
>>> float_info
sys.floatinfo(max=1.7976931348623157e+308, max_exp=1024, max_10_exp=308, 
min=2.2250738585072014e-308, min_exp=-1021, min_10_exp=-307, dig=15, 
mant_dig=53, epsilon=2.2204460492503131e-16, radix=2, rounds=1)
>>> from pickle import dumps, loads
>>> x = 7e-308
>>> x
7.0000000000000004e-308
>>> p = [dumps(x, proto) for proto in range(3)]
>>> p
['F7.0000000000000004e-308\n.', 'G\x00)*\xee\xa4Z\xae\xe0.', 
'\x80\x02G\x00)*\xee\xa4Z\xae\xe0.']
>>> up = [loads(z) for z in p]
>>> up
[7.0000000000000004e-308, 7.0000000000000004e-308, 7.0000000000000004e-
308]
msg91380 - (view) Author: Sridhar Ratnakumar (srid) Date: 2009-08-06 19:13
It is a powerpc 64-bit AIX machine:

>>> os.uname()
('AIX', 'asaixv5152', '1', '5', '000C763E4C00')
>>> platform.uname()
('AIX', 'asaixv5152', '1', '5', '000C763E4C00', 'powerpc')

The commands you have requested:

>>> from sys import float_info
>>> float_info
sys.floatinfo(max=1.7976931348623157e+308, max_exp=1024, 
max_10_exp=308, min=2.2250738585072014e-308, min_exp=-1021, 
min_10_exp=-307, dig=15, mant_dig=53, epsilon=2.2204460492503131e-16, 
radix=2, rounds=1)
>>> from pickle import dumps, loads
>>> x = 7e-308
>>> x
6.9999999999999994e-308
>>> p = [dumps(x, proto) for proto in range(3)]
>>> p
['F6.9999999999999994e-308\n.', 'G\x00)*\xee\xa4Z\xae\xdf.', '\x80\x02G
\x00)*\xee\xa4Z\xae\xdf.']
>>> up = [loads(z) for z in p]
>>> up
[6.9999999999999984e-308, 6.9999999999999994e-308, 
6.9999999999999994e-308]
>>>
msg91382 - (view) Author: Mark Dickinson (mark.dickinson) * (Python committer) Date: 2009-08-06 20:10
Thanks.  So pickle protocol 0 is where it's failing;  protocols 1 and 2 
are okay.  It looks as though there's a problem with double <-> string 
(i.e., binary <-> decimal) conversion here.

This probably also means that there are more serious problems on AIX, 
e.g., that float(repr(x)) == x fails for at least some Python floats x.  
That is, on my system:

>>> x = 7e-308
>>> float(repr(x)) == x
True

I expect that you'd get 'False' for this.  Is that right?  If you do get 
False, does this happen for any randomly chosen float x, or is it just 
very small values like the above that are problematic?

Is there any chance the FPU rounding mode has somehow been set to 
something other than round-to-nearest?  (It seems unlikely, but it's 
worth checking.)

These bits of Python are based on the assumption that conversion of an 
IEEE 754-format C double to a decimal string with 17 significant digits 
and back again recovers the original double.  A conforming hosted 
implementation of C99 that defines __STDC_IEC_559__ should satisfy this 
assumption (see Appendix F of the standard, especially section F.5);  
the IEEE 754 standard also recommends this behaviour.

So if your C implementation defines __STDC_IEC_559__ then this can 
reasonably be considered a platform bug.  Does it?
msg91562 - (view) Author: Mark Dickinson (mark.dickinson) * (Python committer) Date: 2009-08-14 17:14
Closing this as a won't fix:  as far as I can tell, the test failure is 
due to a platform deficiency (string <-> float conversions provided by the 
C standard library aren't correctly rounded; moreover, they're not 
accurate enough that converting a C double to 17 significant digits and 
back recovers the original double).  It's not clear what Python can 
reasonably do to fix this.  I'd prefer not to disable or weaken these 
tests, since they're useful on other platforms.

srid, if you do have any alternative suggestions about how this might be 
fixed then please do submit them.

For what it's worth, this particular failure should no longer be a problem 
in Python 3.1 and higher, since 3.1 uses its own string <-> float 
conversion code (based on David Gay's dtoa.c).
History
Date User Action Args
2009-08-14 17:14:31mark.dickinsonsetstatus: open -> closed
resolution: wont fix
messages: + msg91562
2009-08-06 20:10:17mark.dickinsonsetmessages: + msg91382
2009-08-06 19:13:02sridsetmessages: + msg91380
2009-08-06 09:39:03mark.dickinsonsetmessages: + msg91351
2009-08-06 09:17:51mark.dickinsonsetassignee: mark.dickinson

nosy: + mark.dickinson
2009-08-05 01:42:44sridcreate