代码之家  ›  专栏  ›  技术社区  ›  Adam P

限制浮点精度问题的实践

  •  2
  • Adam P  · 技术社区  · 14 年前

    作为程序员,大多数人(如果不是我们所有人)都知道浮点数有不太准确的倾向。我知道这个问题不能完全避免,但是我想知道是否有一些特定的实践、模式等可以用来至少减少浮点错误。

    事先谢谢。

    2 回复  |  直到 11 年前
        1
  •  2
  •   Borealid    14 年前

    使用定点数学可以处理已知的有限精度。

    例如,Rockbox音乐播放器固件几乎完全使用定点媒体编解码器。

    如果您必须完全准确,请使用像GMP库提供的那样的无限长存储类型。

    如果你只是想减少你的错误,试着尽可能接近零,在那里IEEEFP数字更精确。重新排序操作以避免绝对值过大。

        2
  •  0
  •   Max    11 年前

    浮点精度是一个很大的课题,一些最聪明的计算机科学家多年来一直在研究这个问题。如果你要么没有学习过FP的准确性,要么没有彻底研究过你的CS问题,要么不能依靠其他队友来完全理解,只需坚持双打,而不是32,而是浮动,除非你只是在做电脑绘图或项目要求单打。

    有些任务,如乘法,是交际的。例如,使用python:

    >>>a*a*a*a*a*a    
    1.1044776737696922    
    >>> (a*a*a)*(a*a*a)    
    1.104477673769692    
    >>> (a*a)*(a*a)*(a*a)   
    1.104477673769692
    

    答案是一样的,因为指数只是简单地加在一起,而尾数(1.分数…)只是简单地相乘而没有损失。

    另一方面,如果我们按错误的顺序执行减法和乘法,我们可以得到非常不同的结果。

    B=1.00016789

    B*(B-1)

    0.00016791818705204833

    B*B-B

    0.00016791818705197414

    即使这看起来很好,如果仔细观察,您会发现只有11个十进制数字是正确的。从另一个角度来看, ((b*(b-1)) - (b*b-b))/b 代数上应该是零,但结果是 7.417408056593443e-17 . 这似乎是一个小错误,但浮点错误往往以负的方式累积。我们用的是单精度的吗? float b = 1.00016789 使用C语法,问题会更严重。在这么小的一组操作之后,您只剩下几个可靠的十进制数字了。