测试由于浮点数限制而产生的舍入误差 [英] Testing for rounding errors due to Floating Point limitations

查看:113
本文介绍了测试由于浮点数限制而产生的舍入误差的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最近了解到浮点数的主要限制之一:一些数字不能用二进制正确地表示,因此可能给出的答案不够精确.

I have recently learned about one of the main limitations of floating points: The fact that some numbers can not be represented properly in binary and might therefore give answers which are not accurate enough for your purpose.

知道round(2.675, 2)round(2.665, 2)都等于2.67,我试图编写一些代码,以给出具有此属性的数字列表(四舍五入不正确).

Knowing that round(2.675, 2) and round(2.665, 2) both equal 2.67 I tried to write some code that would give a list of numbers that have this property (being rounded improperly).

请在下面或此重新修改中查看我的代码: https://repl.it/@FTBlover123/Float-Rounding-Test

See my code below or in this replit: 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是本身不准确的self的不正确版本!通过将number1number2分别增加0.001(也不能用二进制表示)可以很容易地证明这一点,因为这也会导致答案仍然不正确,但也有差异!

Though the code indeed seems to return some rounding errors due to the limitations of float, these seem to be non-true values (except for the first one). This is because I am using the float 0.005 (which can not be expressed in binary) which itself causes the new number1 and number2 to be the incorrect version of its already inaccurate self! This is easily demonstrated by incrementing number1 and number2 by 0.001 (which can also not be expressed in binary), as this also results in answers which are still incorrect, but also different!

因此,我的问题:

是否可以创建代码来正确检查由于浮点数限制而导致的舍入错误,而又不会遭受我们试图测试的确切缺陷的困扰? (尽管对此类示例的库也将不胜感激,但我对修复代码更感兴趣)

Is it possible to create code that checks for the rounding errors due to float limitations correctly, without it suffering from the exact flaw we're trying to test for? (Though a library of such examples would also be appreciated I am much more interested in fixing the code)

我的错误输出之间的间隔似乎呈指数级增长.

The separation between my incorrect outputs seems to increase somewhat exponentially.

  • 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

  • 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

是什么原因造成的?对于正确的不正确四舍五入的浮点数也是如此吗?

What causes this? Is this also true for the correct incorrectly rounded floats?

推荐答案

好吧,正如您所注意到的,您不能只继续添加0.005,因为0.005不能表示为浮点数.

Well, as you've noticed, you can't just keep adding 0.005, because 0.005 is not representable as a floating point number.

该怎么办?使用可代表的数字!

What to do instead? Use numbers that ARE representable!

2675可以精确地表示为浮点数(不超过2 ^ 53的每个整数),也可以是1000.因此2675.0/1000.0,虽然不能表示为浮点数,但将四舍五入为最接近的可表示浮点数,就像文字2.675一样. (为此,您可以使用267.5/100.0,但我认为最好坚持使用整数.)

2675 is exactly representable as a float (every integer up to 2^53 is), and so is 1000. So 2675.0/1000.0, while not representable as a float, will be rounded to the closest representable float, just as the literal 2.675 would be. (For that matter, you could use 267.5/100.0, but best to stick to integers, I think.)

因此,与其增加要以这种方式检查的值,不如增加分子并每次进行除法.

So rather than increment the value you intend to check in this way, increment the numerator, and do the division each time.

这篇关于测试由于浮点数限制而产生的舍入误差的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆