python - 测试由于浮点限制而导致的舍入误差

标签 python python-2.7 floating-point binary rounding

我最近了解到浮点的主要局限性之一:事实上,某些数字无法以二进制正确表示,因此可能给出的答案对于您的目的而言不够准确。

知道 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(无法用二进制表示),这本身会导致新的 number1number2 成为其已经不准确的自身的错误版本!这可以通过将 number1number2 增加 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/

相关文章:

Python/Django 生成运行时异常

python - 重新分组值

python - 在 Python 中解析 Javascript

python-2.7 - 如何配置 virtualenvwrapper 与 pyenv 一起使用

c - 溢出与信息

python - 使用 xml.dom.minidom 时在 xml 中转义 '<' 和 '>'

Python:将多维字典的列表转换为字典键,并进行异常处理

javascript - 为什么 13596*0.1 与 13596/10 不同?

python - 将 float 转换为整数时的 Pandas 四舍五入

python - 从列表列表中删除重复项