为啥 Python 3 字符串函数似乎会降低浮点数的精度?

Posted

技术标签:

【中文标题】为啥 Python 3 字符串函数似乎会降低浮点数的精度?【英文标题】:Why does the Python 3 string function appear to reduce precision of float?为什么 Python 3 字符串函数似乎会降低浮点数的精度? 【发布时间】:2018-12-12 19:29:57 【问题描述】:

在 Ubuntu 18 上的 Python (3.6.7) 交互式 shell 中,两者都

>>> n = str(3.140000000000000124344978758017532527446746826171875)
>>> print(n)

>>> print(3.140000000000000124344978758017532527446746826171875)

产量3.14。而

>>> print('3.140000000000000124344978758017532527446746826171875')

收益3.140000000000000124344978758017532527446746826171875

这是为什么?

注意;我不是在问为什么浮点数会丢失精度,而是具体来说,为什么 str(n)'n'(引号)的使用与 print() 的行为不同。

【问题讨论】:

很少有人愿意在print(3.14) 看到3.140000000000000124344978758017532527446746826171875 前两个是将数字转换为字符串,但第三个不涉及任何转换,只是按原样打印字符串 github.com/python/cpython/blob/master/Objects/floatobject.c 相关:***.com/questions/24187684/… “为什么使用 str(n) 和 'n' (引号) 的行为不同” - 它们的行为不应该相同。 str 不应该等同于在表达式周围加上引号。举个超级简单的例子,看看你写的字——你不会期望str(n)'n',除非你指定了n='n',对吗? 【参考方案1】:

在情况 1 和 2 中,您操作的是浮动对象

f = 3.140000000000000124344978758017532527446746826171875

# In case 1
print(str(f))

# In case 2
print(f)

str(f)将float对象转换为字符串,print(f)表示print(repr(f))repr(f)也将float对象转换为字符串。

在情况 3 中,您操作的是一个包含 53 个字符的字符串对象,

将浮点对象转换为字符串时发生了什么?

str(f)repr(f)调用同一个函数float_repr。

在函数float_repr中,如果没有指定精度参数,浮点对象将被转换为双精度浮点格式的字符串。

双精度浮点格式提供 15 到 17 位有效十进制数字的精度。

所以在这种情况下,有效十进制数字精度为 16,3.140000000000000124344978758017532527446746826171875 将转换为 3.140000000000000

一个更清楚的例子:

>>> str(3.140000000000000123)
'3.14'

>>> str(3.14000000000000123)
'3.140000000000001'

>>> print(3.14000000000000123)
3.140000000000001

【讨论】:

以上是关于为啥 Python 3 字符串函数似乎会降低浮点数的精度?的主要内容,如果未能解决你的问题,请参考以下文章

为啥matlab中的ncread函数会减少浮点数? [复制]

为啥python使用eval函数输出结果有很多尾数

从错误中学python————字符串转浮点数

为啥 C 没有无符号浮点数?

JavaScript为啥浮点数会丢失精度

python中奇怪的浮点数到整数转换问题