浮点模数问题

时间:2010-02-24 02:33:03

标签: python floating-point floating-accuracy

我偶然发现了一个非常奇怪的错误。阅读代码中的注释以查看错误是什么,但实际上变量modulo 1返回1(但它不等于1!)。我假设有一个显示问题,浮动非常接近一个但不完全。但是,它应该模数为零。我不能轻易地测试这个案例,因为(最后%1)!= 1.0!当我尝试将相同的数字插入另一个python终端时,一切都表现正常。发生了什么事?

def r(k,i,p):
    first = i*p
    last = first + p

    steps = int((i+1)*p) - int(i*p)
    if steps < 1:
        return p
    elif steps >= 1:
        if k == 0:
            return 1 - (first % 1)
        elif k == steps:
            if i == 189:
                print last, 1, type(last), last % 1, last - int(last)
                # Prints: 73.0 1 <type 'float'> 1.0 1.0
                print last % 1 == 1 # Returns False
            if last % 1 == 1.0:
                return 0
            return (last % 1)
        else:
            return 1

5 个答案:

答案 0 :(得分:6)

欢迎使用IEEE754,enjoy your stay

答案 1 :(得分:6)

打印未显示存储的数字的完整精度,您可以使用repr()来执行此操作

>>> last=72.99999999999999
>>> print last, 1, type(last), last % 1, last - int(last)
73.0 1 <type 'float'> 1.0 1.0
>>> print last % 1 == 1
False
>>> print repr(last), 1, type(last), repr(last%1), repr(last - int(last))
72.999999999999986 1 <type 'float'> 0.99999999999998579 0.99999999999998579
>>> 

答案 2 :(得分:3)

你应该使用math.fmod(x,y)。以下摘自http://docs.python.org/library/math.html

“请注意,Python表达式x%y可能不会返回相同的结果.C标准的目的是fmod(x,y)完全(数学上;到无限精度)等于x - n * y for一些整数n使得结果具有与x相同的符号,并且幅度小于abs(y).Python的x%y返回带有y符号的结果,并且可能不能完全计算浮点参数。例如,fmod (-1e-100,1e100)是-1e-100,但是Python的-1e-100%1e100的结果是1e100-1e-100,它不能完全表示为浮点数,而转向令人惊讶的1e100 。因此,使用浮点数时通常首选函数fmod(),而使用整数时,首选Python的x%y。“

答案 3 :(得分:1)

您可以尝试math.fmod功能而不是last % 1,也许它更适合您的问题。 或者您可以在整数空间中重构问题。

无论如何,使用相等==运算符比较浮点数值并不是一个好习惯,因为即使是来自0.1 + 0.2 == 0.3

之类的简单操作也会导致不精确的结果

答案 4 :(得分:0)

如果您需要任意精度,那么有一些项目可以做到这一点。 gmpy处理多精度整数,mpmath看起来非常好,bigfloat包装MPFR。通过gnibbler的回答,你所拥有的就足够了,但是,以防万一。