所以我有一个元组列表,每个元组包含两个float。每个元组代表一个范围。我正在查看另一个浮动列表,这些浮点数表示适合范围的值。所有这些浮点值都是<;1但为正,因此精度很重要。我用来确定某个值是否适合某个范围的一个测试在它应该通过时失败了。如果我打印出引起问题的值和范围,我可以知道很多:
curValue = 0.00145000000671
range = (0.0014500000067055225, 0.0020968749796738849)
失败的条件是:
^{pr2}$从curveValue和range给出的值来看,测试应该很清楚地通过了(不要担心条件中的内容)。现在,如果我显式打印范围[0]的值,我得到:
range[0] = 0.00145000000671
这就可以解释为什么测试失败了。所以我的问题是,为什么在访问时浮动会改变。当它是元组的一部分时,它具有高达某个精度的十进制值,而在访问时则具有不同的精度。为什么会这样?如何确保数据在计算过程中保持一致的精度?在
在现代电脑的浮动不是那么精确。所以,即使你把π作为一个常数输入到100个小数点,它也只能得到其中几个小数点的精确值。同样的事情也发生在你身上。这是因为在32位浮点运算中,你只能得到24位尾数,这限制了你的精度(因为它在base2中,所以以意想不到的方式)。在
请注意,
0.00145000000671
不是Python存储的确切值。如果使用print
,Python只显示完整存储浮点的几个小数位数。如果您想知道python是如何存储float的,请使用repr
。在如果您想获得更好的精度,请使用^{} 模块。在
它本身并不是在改变。Python尽力将数据存储为float,但是这个数字对于float来说太精确了,所以Python甚至在访问它之前(在存储它的过程中)对它进行了修改。有趣的是,这么小的事情是如此的痛苦。在
您需要使用任意不动点模块,如Simple Python Fixed Point或decimal模块。在
浮动不变。内置的数字类型都是不可变的。你观察到的原因是:
print range[0]
在float上使用str
,这(直到Python的最新版本)打印的浮点数更少。在repr
还是str
)在单个项上使用repr
,这样可以提供更准确的表示(同样,在最近的版本中,这不再是真的了,因为它们都使用了更好的算法)。在至于为什么条件没有按你期望的方式运行,很可能是常见的罪魁祸首,浮动精度有限。尝试
print repr(curVal), repr(range[0])
看看Python决定的是不是最接近于float文本的表示。在相关问题 更多 >
编程相关推荐