Floating point 浮点错误的真实例子

Floating point 浮点错误的真实例子,floating-point,Floating Point,是否有任何公司被浮点数据烧掉的例子导致舍入问题?我们正在实施一个新系统,所有的货币价值都存储在浮动中。我想,如果我能给出失败原因的实际例子,它将比无法正确存储值的理论更重要。这些来自嵌入式世界(Ariane 5,Patriot),但严格意义上不是浮点舍入错误。Ariane 5错误是转换中的错误。爱国者bug是在软件的修改过程中引入的。它涉及到不同精度的计算,具有一个固有的不可表示常数(恰好是看起来无害的0.10) 我预见到货币价值的二进制浮动存在两个问题: 像0.10这样常见的十进制值无法准确

是否有任何公司被浮点数据烧掉的例子导致舍入问题?我们正在实施一个新系统,所有的货币价值都存储在浮动中。我想,如果我能给出失败原因的实际例子,它将比无法正确存储值的理论更重要。

这些来自嵌入式世界(Ariane 5,Patriot),但严格意义上不是浮点舍入错误。Ariane 5错误是转换中的错误。爱国者bug是在软件的修改过程中引入的。它涉及到不同精度的计算,具有一个固有的不可表示常数(恰好是看起来无害的0.10)

我预见到货币价值的二进制浮动存在两个问题:

  • 像0.10这样常见的十进制值无法准确表示

  • 如果精度太小,可能引发异常的干净溢出将变成难以跟踪的精度损失


请注意,base-10浮点格式已经针对货币值进行了精确的标准化:某些货币值为1/1000000美元,兑换金额永远不会少于数千美元,并且您可能希望能够表示的最大金额是成比例的,因此可伸缩表示是有意义的。其目的是,尾数要足够大,以满足官方决议中最大金额的要求。

我在一个计算人们加薪和奖金的系统上工作。由于部分的数量(公司绩效、部门绩效、个人绩效),计算相对复杂,但每个部分都足够简单(通常为复合百分比),例如:

个人奖金=工资*个人奖金百分比

部门奖金=个人奖金*50%

公司奖金=个人奖金*110%

奖金总额=个人奖金+部门奖金+公司奖金

其中,个人奖金百分比是根据奖金罐的大小、个人的评级和拥有该评级的人员计算得出的值


当我们测试时,我们没有手动计算(即在纸上)结果应该是什么,而是将它们与运行相同公式的Excel进行比较。员工们确实在纸上做了计算,当我们重写算法来解决浮点问题时,大约5%的奖励是错误的。

我认为你不会找到真正被烧死的人。我听说过一些公司,工资单或利息程序使用浮点而不是固定小数,程序员从所有账户中收集小数点位进行盗用,而账户持有人没有发出警报。但是,这种事情通常在几年前就悄悄地解决了。现在有了最佳实践规则来防止这类事情

另一种方法是,如果你试图从一个小样本中进行推断,误差可能会大到让你绊倒。就像在一个小镇上进行民意调查,并试图预测全国的流行结果


前几个月我在做一个项目,我们用矩阵数学计算校准曲线的多项式。我们程序中的系数与电子表格中的系数完全不同。当我检查了程序和电子表格,并将所有内容四舍五入到正确的有效位数时,他们非常同意。当垃圾与垃圾相乘,然后平方或立方时,它就成了一个问题

我能想到的唯一真正的FPU错误是浮点数上的相等比较。例如,0.123456和0.123457非常接近;事实上,如果它们都是舍入误差可能累积的一系列计算的结果,那么它们很可能是相等的。与其与==进行比较,不如编写一个模糊等式,确定它们是否足够接近,从而被视为相等


一个快速的谷歌搜索打开了这个页面,它详细介绍了与fuzzy equals函数相关的注意事项

我在一个团队工作,该团队创建了一个FPU(硬件设计),通过了单精度、双精度和扩展精度的testfloat 3级测试。有很多糟糕的FPU,如果它们能够捕获指令或异常,大部分都是在软件中修补的,诸如此类。我想testfloat的家伙说主要的fpu错误在int-to-float和float-to-int转换中,我记得奔腾4就是因为这个原因失败的。不过奔腾III我已经通过了测试。我已经有一段时间没试过了,不知道这些多核处理器的状态如何。不要被愚弄到认为pentium I是唯一有错误的,几乎所有的公司,当然是更大的公司,都有fpu错误。IEEE754是一个可怕的标准,要让fpu达到这个标准是非常困难和昂贵的,在那次经历之后,我尽可能避免浮点数学。编译器和c库(atof、ftoa、STROD、printf等)是问题的一部分,而不仅仅是硬件

单精度浮点只有23位尾数,你会经常扔掉几便士、几美元或几千美元。有或没有四舍五入。如果数据是随机的,那么四舍五入应该是平均的,这里得一分,那里输一分。如果被跟踪的项目总是在某个固定大小或数量有限的单元中。如果widgets的价格是9.99或15.99,那么随机性就会消失,取整和尾数都会让公司或客户损失准确性

当然,在0.00和0.99之间可能有很多数字是你无法表示的,如果你处理的是小数量,你将很快进入四舍五入

用浮子来赚钱是个坏主意,也许你在寻找弹药来改变这一点

double: 1.000167890
single: 1.000167847
(b*(b-1)) - (b*b-b):  0.0000000281725079
(a*(a-1)) - (a*a-a):  0.0000000000000001
resultSmall - result: 0.000000028172507807931691
double^12 - single^12:0.000000593091349143648472