Precision issue

Duncan Booth duncan at NOSPAMrcp.co.uk
Mon Oct 13 04:19:06 EDT 2003


"Tim Peters" <tim.one at comcast.net> wrote in
news:mailman.1065811102.23755.python-list at python.org: 

>> There's no reason why Python couldn't do the same:
>>
>> def float_repr(x):
>>      s = "%.15g" % x
>>      if float(s)==x: return s
>>      return "%.17g" % x
> 
> Sorry, but there is a reason:  if done on a platform whose C library
> implements perfect-rounding double->string (e.g., I think gcc does
> now), this can hit cases where the string may not reproduce x when
> eval'ed back on a different platform whose C library isn't so
> conscientious but which nevertheless meets the 754 standard's more
> forgiving (than perfect rounding) requirements.
> 
> This is acutely important because Python's marshal format (used for
> .pyc files) represents floats as repr'ed strings.  By making repr()
> pump out 17 digits, we maximize the odds that .pyc files ported across
> platforms load back exactly the same 754 doubles across (754)
> platforms. 

Thanks for giving me the reason, but I find this argument unconvincing on 
several counts.

If a system has an inaccurate floating point library, then introducing 
further inconsistencies based on whether the .pyc file was compiled locally 
or copied from another system doesn't sound like a good solution. Surely if 
the library is inaccurate you are going to get inaccurate results no matter 
what tweaks Python tries to apply?

Also the marshal code doesn't actually use repr. For that matter the 
interactive prompt which is what causes the problems I want to avoid in the 
first place doesn't use repr either! (Marshal uses PyFloat_AsReprString 
which comments say should be deprecated, repr uses float_repr, and 
interactive mode uses float_print.) If you think it is important, I don't 
have any problems with leaving the marshalling code generating as many 
digits as it wants.

-- 
Duncan Booth                                             duncan at rcp.co.uk
int month(char *p){return(124864/((p[0]+p[1]-p[2]&0x1f)+1)%12)["\5\x8\3"
"\6\7\xb\1\x9\xa\2\0\4"];} // Who said my code was obscure?




More information about the Python-list mailing list