Converting a Python Float to a String without losing precision

后端 未结 5 828
被撕碎了的回忆
被撕碎了的回忆 2021-02-01 03:40

I am maintaining a Python script that uses xlrd to retrieve values from Excel spreadsheets, and then do various things with them. Some of the cells in the spreadshe

5条回答
  •  旧巷少年郎
    2021-02-01 04:25

    I'm the author of xlrd. There is so much confusion in other answers and comments to rebut in comments so I'm doing it in an answer.

    @katriealex: """precision being lost in the guts of xlrd""" --- entirely unfounded and untrue. xlrd reproduces exactly the 64-bit float that's stored in the XLS file.

    @katriealex: """It may be possible to modify your local xlrd installation to change the float cast""" --- I don't know why you would want to do this; you don't lose any precision by floating a 16-bit integer!!! In any case that code is used only when reading Excel 2.X files (which had an INTEGER-type cell record). The OP gives no indication that he is reading such ancient files.

    @jloubert: You must be mistaken. "%.40r" % a_float is just a baroque way of getting the same answer as repr(a_float).

    @EVERYBODY: You don't need to convert a float to a decimal to preserve the precision. The whole point of the repr() function is that the following is guaranteed:

    float(repr(a_float)) == a_float
    

    Python 2.X (X <= 6) repr gives a constant 17 decimal digits of precision, as that is guaranteed to reproduce the original value. Later Pythons (2.7, 3.1) give the minimal number of decimal digits that will reproduce the original value.

    Python 2.6.4 (r264:75708, Oct 26 2009, 08:23:19) [MSC v.1500 32 bit (Intel)] on win32
    >>> f = 0.38288746115497402
    >>> repr(f)
    '0.38288746115497402'
    >>> float(repr(f)) == f
    True
    
    Python 2.7 (r27:82525, Jul  4 2010, 09:01:59) [MSC v.1500 32 bit (Intel)] on win32
    >>> f = 0.38288746115497402
    >>> repr(f)
    '0.382887461154974'
    >>> float(repr(f)) == f
    True
    

    So the bottom line is that if you want a string that preserves all the precision of a float object, use preserved = repr(the_float_object) ... recover the value later by float(preserved). It's that simple. No need for the decimal module.

提交回复
热议问题