Python中浮点数精度丢失
我有一个叫做 scores 的列表,里面存的是不同的负对数概率。
当我调用这个函数时:
maxState = scores.pop(scores.index(max(scores)))
然后打印 maxState
,我发现 maxState
作为浮点数的时候,精度丢失了。有没有办法让我得到不失去精度的 maxState 呢?
比如,我打印出列表 scores:[-35.7971525669589, -34.67875545008369]
,然后打印 maxState,结果是:-34.6787554501
(你可以看到它被四舍五入了)
1 个回答
你可能把字符串的显示方式和实际内容搞混了。其实并没有丢失精度,只是你在控制台看到的字符串是用一个四舍五入的值,而不是显示所有的数字。要记住,浮点数是数字的近似值,而不是精确值。
在Python中,使用 str()
和 repr()
函数时,浮点数的格式是不同的;在列表或其他容器中会使用 repr()
,但如果直接打印出来,就会用 str()
。
如果你对这两种方式都不满意,可以使用 format()
函数 来明确指定格式和精度:
print format(maxState, '.12f')
比如说,你想打印出8位小数。
示例:
>>> maxState = -34.67875545008369
>>> repr(maxState)
'-34.67875545008369'
>>> str(maxState)
'-34.6787554501'
>>> format(maxState, '.8f')
'-34.67875545'
>>> format(maxState, '.12f')
'-34.678755450084'
repr()
的输出大致相当于使用 '.17g'
作为格式,而 str()
则相当于 '.12g'
;这里的精度决定了什么时候使用科学计数法(e
)和什么时候使用浮点数表示法(f
)。
我说“大致”是因为 repr()
的输出旨在提供可以回溯的结果;你可以查看 Python 3.1 的浮点数表示变化说明,这些变化也被移植到了 Python 2.7:
新的变化在于数字的显示方式。以前,Python使用一种简单的方法。
repr(1.1)
的值是通过format(1.1, '.17g')
计算得出的,结果是'1.1000000000000001'
。使用17位数字的好处是,它依赖于IEEE-754标准的保证,确保eval(repr(1.1))
能准确返回原始值。缺点是很多人觉得这个输出让人困惑(把二进制浮点表示的固有限制误认为是Python本身的问题)。现在
repr(1.1)
的新算法更聪明,返回的是'1.1'
。实际上,它会搜索所有等效的字符串表示(那些存储着相同底层浮点值的表示),并返回最短的表示方式。