Floating point 限制浮点精度问题的实践

Floating point 限制浮点精度问题的实践,floating-point,Floating Point,作为程序员,大多数人(如果不是我们所有人的话)都知道浮点数有不太准确的倾向。我知道这个问题无法完全避免,但我想知道是否有任何特定的实践、模式等可以用来至少减少浮点错误 提前感谢。使用定点数学,您可以处理已知的有限精度 例如,Rockbox音乐播放器固件几乎完全使用定点媒体编解码器 如果必须完全准确,请使用GMP库提供的无限长存储类型 如果你只是想减少你的错误,试着尽可能接近于零,因为IEEE FP数字更精确。重新排序操作以避免绝对值过大。浮点精度是一个大课题,一些最聪明的计算机科学家多年来一直在

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


提前感谢。

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

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

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


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

浮点精度是一个大课题,一些最聪明的计算机科学家多年来一直在研究这个问题。如果你没有研究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
。这似乎是一个小错误,但浮点错误往往以一种消极的方式累积起来。如果我们使用单精度浮点b=1.00016789,使用C语法,问题会更严重。在完成如此小的一组操作之后,您将只剩下几个可靠的十进制数字。

我认为Rockbox优先使用定点编解码器,因为它的一些目标没有FPU,因此性能将不充分。我不认为准确性是一个主要问题——如果是的话,我们将在台式机上使用Tremor而不是libvorbis。这样,您就不会因为总和的大小增加而遭受精度损失。然而,这会增加一些开销,所以如果速度比精度更重要,甚至不用担心。