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