Python 浮动打印不一致。为什么它有时会起作用?
使用以下(接近最小值)示例: 我们得到:Python 浮动打印不一致。为什么它有时会起作用?,python,python-3.x,numpy,Python,Python 3.x,Numpy,使用以下(接近最小值)示例: 我们得到: 0.0 0.1 0.2 0.30000000000000004 0.4 0.5 0.6000000000000001 0.7000000000000001 0.8 0.9 1.0 1.1 1.2000000000000002 1.3 1.4000000000000001 1.5 1.6 1.7000000000000002 1.8 1.9000000000000001 作为输出 我知道“浮点数精度问题”是导致X.X000001输出的原因,但我不明白的是
0.0
0.1
0.2
0.30000000000000004
0.4
0.5
0.6000000000000001
0.7000000000000001
0.8
0.9
1.0
1.1
1.2000000000000002
1.3
1.4000000000000001
1.5
1.6
1.7000000000000002
1.8
1.9000000000000001
作为输出
我知道“浮点数精度问题”是导致X.X000001输出的原因,但我不明白的是它为什么有时会起作用。很明显,0.3不能用一个浮点数精确地表示在基数2中,而且我看不到数字中没有显示只有一个十进制数字的任何模式
Python为什么知道0.1足以显示一个数字?什么样的魔法让它截断剩下的数字?为什么它只在某些时候工作?您正在打印
numpy.float64
对象,而不是Python内置的float
类型,它使用
截至,numpy使用,已调整为接近Pythonfloat
type使用的David Gay算法的输出:
Numpy标量在str/repr的“unique”模式(见下文)中使用dragon4算法,其方式试图匹配python浮点输出
该文件将对此进行更详细的说明:
unique
:布尔值,可选
如果True
,请使用数字生成策略,该策略通过明智的四舍五入,提供最短的表示形式,唯一地将浮点数与相同类型的其他值区分开来。如果省略了精度,则打印出所有必要的数字,否则在精度数字之后,数字生成将被切断,剩余值将被舍入
因此,只能通过打印0.2
来唯一地表示0.2
,但是序列中的下一个值(0.300000000004
)不能唯一地表示,您必须包含额外的数字以唯一地表示准确的值
这实际上是如何涉及的;你可以在Bungie's Destiny游戏工程师Ryan Juckett的网站上看到关于这一点的完整报告
但基本上,输出字符串的代码需要确定围绕可能的浮点数聚集的所有十进制数的最短表示形式,这些浮点数不能解释为下一个或上一个可能的浮点数:
这张图片来自by,它也涵盖了其他一些案例。蓝色的数字可能是float64
值,绿色的数字可能是十进制数字的表示形式。请注意灰色的中间点标记,任何位于浮动值周围的两个中间点之间的表示都是公平的,因为所有这些表示都会产生相同的值
David Gay和Dragon4算法的目标都是找到最短的十进制字符串输出,以再次产生完全相同的浮点值。从:
Python现在使用David Gay的算法来寻找不改变其值的最短浮点表示。这将有助于减轻围绕二进制浮点数的一些混淆
用像1.1
这样的数字很容易看出其重要性,它在二进制浮点中没有精确的等价物。由于没有完全等效的表达式,像float('1.1')
这样的表达式计算为最接近的可表示值,即十六进制形式的0x1.199999999AP+0
,或十进制形式的1.1000000000000088817841970012523233890533447265625
。该最近值过去和现在都在后续浮点计算中使用
新的是数字的显示方式。以前,Python使用一种简单的方法。repr(1.1)
的值被计算为格式(1.1,.17g')
,计算结果为'1.10000000000001'
。使用17位数字的优势在于,它依赖IEEE-754保证,以确保eval(repr(1.1))
将精确往返到其原始值。缺点是许多人发现输出令人困惑(误认为二进制浮点的固有限制)
表示为Python本身的一个问题)
repr(1.1)
的新算法更智能,返回'1.1'
。实际上,它搜索所有等价的字符串表示形式(使用相同的基础浮点值存储的字符串表示形式),并返回最短的表示形式
新算法在可能的情况下倾向于发出更清晰的表示,但它不会更改基础值。因此,1.1+2.2!=3.3
即使陈述可能另有建议
您正在打印
numpy.float64
对象,而不是Python内置的float
类型,该类型使用
截至,numpy使用,已调整为接近Pythonfloat
type使用的David Gay算法的输出:
Numpy标量在str/repr的“unique”模式(见下文)中使用dragon4算法,其方式试图匹配python浮点输出
该文件将对此进行更详细的说明:
unique
:布尔值,可选
如果True
,请使用数字生成策略,该策略通过明智的四舍五入,提供最短的表示形式,唯一地将浮点数与相同类型的其他值区分开来。如果省略了精度,则打印出所有必要的数字,否则在精度数字之后,数字生成将被切断,剩余值将被舍入
因此,只能通过打印0.2
来唯一地表示0.2
,但是序列中的下一个值(0.300000000004
)不能唯一地表示,您必须包含额外的数字以唯一地表示准确的值
这实际上是如何涉及的;你可以在Bungie's Destiny游戏工程师Ryan Juckett的网站上看到关于这一点的完整报告
但基本上,输出字符串的代码需要确定围绕可能的浮点数(不能解释为下一个o)聚集的所有十进制数的最短表示形式
0.0
0.1
0.2
0.30000000000000004
0.4
0.5
0.6000000000000001
0.7000000000000001
0.8
0.9
1.0
1.1
1.2000000000000002
1.3
1.4000000000000001
1.5
1.6
1.7000000000000002
1.8
1.9000000000000001