我尝试在Python这个简单的数学运算Python的数学精度
>>> math.floor(8.2-0.21)
7.0
>>> math.floor(8.21-0.2)
8.0
>>> math.floor(8.2-0.2)
7.0
第三个应该返回8,但它是返回7?
UPDATE
我已经尝试在PHP,Ruby和JAVA,我已经得到了相同的结果。
更新2 我不知道为什么这个问题得到很多票下来!
我尝试在Python这个简单的数学运算Python的数学精度
>>> math.floor(8.2-0.21)
7.0
>>> math.floor(8.21-0.2)
8.0
>>> math.floor(8.2-0.2)
7.0
第三个应该返回8,但它是返回7?
UPDATE
我已经尝试在PHP,Ruby和JAVA,我已经得到了相同的结果。
更新2 我不知道为什么这个问题得到很多票下来!
的语言您引用IEEE-754 64位二进制浮点或使用底层硬件的浮点,这可能是IEEE-754二进制浮点。
在IEEE-754 64位二进制浮点数中,8.2的最接近的可表示值是8.199999999999999289457264239899814128875732421875,最接近的可表示值为0.2。200000000000000011102230246251565404236316680908203125.
所以,当你写8.2 - 0.2
,实际发生的事情是,0.200000000000000011102230246251565404236316680908203125从8.199999999999999289457264239899814128875732421875扣除。结果是略低于8的值,并且稍低于8的值的底面是7.
这里的教训是浮点算法通常是近似的,所以在评估具有不连续性的函数时您必须小心(比如地板)或陡坡。您必须设计代码以接受可能跨越不连续点的结果,或者必须设计计算以避免跨越不连续点的错误。
很好的回答,谢谢 – shox
很好的回答... –
你的前两个例子是可以预料的:
8.2 - 0.21
是7.99
。 7.99
的楼层是7
,这就是返回的内容。请记住,floor(x)
是小于或等于x
的最大整数。 8
大于7.99
,因此不可能被退回。另一方面,7
符合此要求。
8.21 - 0.2
是8.01
。 8.01
的地板是8
- 这里没有魔法。
>>> math.floor(8.2-0.2)
7.0
现在,这是更有趣。它有一个事实,即8.2
和0.2
不能准确地用辆彩车代表做,这样计算的结果或许不是你可能有什么想法:
>>> 8.2 - 0.2
7.999999999999999
再次,floor()
工作as documented。
你可以看到这个自己使用decimal
为:
>> from decimal import Decimal
>>> Decimal(0.2)
Decimal('0.200000000000000011102230246251565404236316680908203125')
>>> Decimal(8.2)
Decimal('8.199999999999999289457264239899814128875732421875')
相关:What Every Computer Scientist Should Know About Floating-Point Arithmetic
@EricPostpischil没关系,你是对的 - 我在想0.8。该错误本身来自“8.2”和“0.2”。我会更新答案。 – arshajii
为什么它应该是8?楼层函数返回最近的整数向下舍去,所以这两个例子都是正确的。
8.2 - 0.21 = 7.99,其向下舍入为7
8.21 - 0.2 = 8.01Hz,其向下舍入为8
>>> a=0.2
>>> a
0.20000000000000001
>>> b = 8.2
>>> b
8.1999999999999993
>>> b-a
7.9999999999999991
>>> math.floor(b-a)
7.0
由于浮点不精确
你的数学错了我认为......也许你想'math.round'? –
你在每个人都回答你之后编辑它,但你的第三个例子是浮点错误。 – roippi
我的意思是8.2 - 0.2,我已更新问题 – shox