我正在使用python 2.7.6。当我在解释器中键入它时
>>> 0.135-0.027
0.10800000000000001
它应该只是
0.108
这会在比较事物时引起问题,例如我想比较
>>> 0.135-0.027 <= 0.108
False
我希望这个答案为真。我是否必须使用能够正确处理浮子的特殊包装?有没有办法以另一种方式解决这个问题?例如,我们可以使用
强制浮动除法from __future__ import division
这个问题是否有类似的解决方案?
答案 0 :(得分:2)
你可以做各种各样的事情,但每种都有各自的优点和缺点。
基本问题是从十进制到任何有限二进制表示的转换涉及舍入。例如,如果您使用IEEE四倍精度,这些情况会更少见,但仍会发生。
您可以使用十进制库或任意精度库,但如果必须进行数万亿次计算,您可能不愿意在运行时支付使用它们的费用。
在这种情况下,你必须问自己一个问题,“我确实知道这些数字的准确程度如何?”然后你可以考虑,“0.135-0.027 <= 0.108
是否可以允许被认为是真的吗?“在大多数情况下,这些问题的答案是”不准确“和”是“,你的问题就解决了。你可能会对这个解决方案感到不舒服,但它是摆动和环形交叉:错误 将“双向”发生(从某种意义上说,有时比较会在成功时失败,并且有时它会在失败时成功。)
如果单向失败是完全正常的,但是以其他方式失败绝对不是,您可以更改硬件的舍入模式(以适应您想要的偏差),或者您可以添加/减去ULP(以适应你想要的偏见。)
例如,请考虑以下内容(抱歉 C ,但我确信您明白了这一点):
double add_ulp(double x) {
union {
double x;
unsigned sign : 1;
unsigned expo : 11;
unsigned long mant : 52;
} inc;
inc.x = x;
inc.mant = 0;
if (inc.expo >= 52 ) {
inc.expo -= 52;
return x+inc.x;
}
return x;
}
你可以这样使用:
if( x-y <= add_ulp(z) ) {
// ...
}
它会在你的案例中为你提供的答案,但它会对你的结果产生偏见。如果这是你想要的偏见,那就不是问题,但如果不是,那就比你现在的问题更糟。
希望这有帮助。
答案 1 :(得分:-1)
这可能会有所帮助: https://pythonhosted.org/bigfloat/
您也可以使用此控制精度。