我最近了解到浮点的主要局限性之一:事实上,某些数字无法以二进制正确表示,因此可能给出的答案对于您的目的而言不够准确。
知道 round(2.675, 2)
和 round(2.665, 2)
都等于 2.67
我尝试编写一些代码给出具有此属性的数字列表(未正确舍入)。
请参阅下面或此重复中的我的代码: https://repl.it/@FTBlover123/Float-Rounding-Test
Test = True
number1 = 0.005
number2 = 0.015
count = 0
count_per_test = 5
while Test:
if round(number1, 2) == round(number2, 2):
print number1, number2, round(number1, 2), round(number2, 2)
count += 1
else:
pass
number1 += 0.005
number2 += 0.005
if count == count_per_test:
answer = raw_input("End Program? Y / N: ")
if answer == "Y":
print "Program Ended"
Test = False
elif answer == "N":
print "Searching For %s more rounding errors" % (count_per_test)
count = 0
else:
print "Error, raw_input incorrect"
Test = False
#2.675 is a known number with a rounding error.
print 2.665, 2.675, round(2.675, 2), round(2.665, 2)
#79.705 should have one according to the results, but it doesn't truly.
print 79.695, 79.705, round(79.695, 2), round(79.705, 2)
最后 2 个 print
就是其中一个示例。
虽然由于 float 的限制,代码确实似乎返回了一些舍入错误,但这些似乎是非真值(第一个除外)。
这是因为我使用的是 float 0.005(无法用二进制表示),这本身会导致新的 number1
和 number2
成为其已经不准确的自身的错误版本!这可以通过将 number1
和 number2
增加 0.001(也不能用二进制表示)来轻松证明,因为这也会导致答案仍然不正确,但也不同!
因此,我的问题是:
是否可以创建代码来正确检查由于浮点限制而导致的舍入错误,而不会遭受我们正在尝试测试的确切缺陷? (虽然我们也希望有这样的示例库,但我对修复代码更感兴趣)
我的错误输出之间的间隔似乎呈指数增长。
0.005 0.015 0.01 0.01
0.035 0.045 0.04 0.04
1.025 1.035 1.03 1.03
21.535 21.545 21.54 21.54
79.695 79.705 79.7 79.7
9164.075 9164.085 9164.08 9164.08
36933.455 36933.465 36933.46 36933.46
这是什么原因造成的?对于正确的错误舍入的 float 来说也是如此吗?
最佳答案
嗯,正如您所注意到的,您不能只是不断地添加 0.005,因为 0.005 不能表示为 float 。
该怎么办?使用可代表的数字!
2675 可以精确地表示为 float (2^53 以内的每个整数都可以),1000 也是如此。因此 2675.0/1000.0
,虽然不能表示为 float ,会 四舍五入到最接近的可表示 float ,就像文字 2.675
一样。 (就此而言,您可以使用 267.5/100.0
,但我认为最好坚持使用整数。)
因此,不要以这种方式增加您要检查的值,而是增加分子,然后每次进行除法。
关于python - 测试由于浮点限制而导致的舍入误差,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51840328/