浮点错误的实际例子

时间:2010-04-28 20:21:55

标签: floating-point

是否有任何公司被浮点数据烧毁导致舍入问题?我们正在实施一个新系统,所有货币值都存储在浮点数中。我想如果我能够展示为什么会失败的实际例子,那么它的重要性将超过为什么价值无法正确存储的理论。

6 个答案:

答案 0 :(得分:3)

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

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

  • 与0.10一样的十进制值无法准确表示。

  • 如果精度太小,那么可能导致异常的干净溢出会导致难以跟踪的精度损失。

请注意,基本10种浮点格式已针对货币价值进行了精确标准化:某些货币的价值为1/1000000美元,永远不会少于数千种,以及您可能希望能够达到的最大金额表示比例大,因此可伸缩表示是有意义的。目的是尾数足够大,以获得官方决议的最大总和。

答案 1 :(得分:1)

我参与了一个创建FPU(硬件设计)的团队,该团队通过testfloat level 3获得单精度,双精度和扩展精度。有许多不好的fpus,如果他们可以捕获指令或异常,大多数都是用软件修补的,那种事情。我认为testfloat的家伙说主要的fpu错误在int中浮动并浮动到int转换,我记得奔腾4因为这个原因失败了。奔腾III虽然通过了testfloat。我有一段时间没试过,不知道这些多核处理器的状态是什么。不要误以为奔腾我是唯一一个有错误的人,几乎所有人,肯定是规模较大的公司,都有fpu错误。 IEEE 754是一个可怕的标准,获得满足该标准的fpu是非常困难且非常昂贵的,在那次经历之后我尽可能避免浮点数学。编译器和c库(atof,ftoa,strtod,printf等)是问题的一部分,而不仅仅是硬件。

单精度浮点数只有23位尾数,你将开始抛弃便士或美元或数千美元。有无圆角。如果数据足够随机,那么舍入应该平均得到一分钱在那里输掉一分钱。如果被跟踪的项目总是处于某个固定大小或有限数量的单位。说小工具在9.99或两个15.99然后随机性消失和四舍五入以及尾数将花费一些人的准确性,无论是公司还是客户。

当然可能有很多介于0.00和0.99之间的数字,你无法代表,如果你处理的数量很少,你将很快进入四舍五入。

使用花车赚钱只是一个坏主意,也许你正在寻找弹药来改变它?

我们有一个由使用单精度fpu的软件驱动的电机控制器,有一部分控制算法,常量必须加起来1.0,我不知道这个规则,我只是让一个C程序计算常数。我们必须手动调整其中一个常数上的尾数的lsbit,以使电机控制器稳定下来。

答案 2 :(得分:0)

我研究了一个计算人们加薪和奖金的系统。由于零件数量(公司业绩,部门业绩,个人业绩),计算相对复杂,但每个部分都很简单(通常是复合百分比),如:

personal_bonus = salary * personal_bonus_percentage

department_bonus = personal_bonus * 50%

company_bonus = personal_bonus * 110%

total_bonus = personal_bonus + department_bonus + company_bonus

其中personal_bonus_percentage是基于奖金底池的大小,该人的评级以及具有该评级的人的计算值。

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

答案 3 :(得分:0)

我认为你不会发现任何真正被烧伤的人。我听说有工资单或兴趣程序使用浮点而不是固定小数的公司,程序员从所有账户中收集了小数位,以便在账户持有人不发出警报的情况下进行套利。但是,这种事情通常在几年前就已经悄然解决了。现在有一些最佳实践规则可以防止出现这种情况。

如果你尝试从一个小样本中推断,那么误差可能会大到足以使你绊倒的另一种方式。就像在一个小镇上进行民意调查并试图预测整个国家的流行结果一样。

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

答案 4 :(得分:0)

我能想到的唯一真正的FPU错误是浮点数的相等比较。例如,0.123456和0.123457非常接近;实际上,如果它们都是一系列计算的结果,它们很可能是平等的,其中舍入误差可能累积。您应该创建一个模糊等于而不是与==进行比较,以确定它们是否足够接近以至于被视为相等。

快速谷歌搜索出现在这个页面上,关于模糊等于函数的相关警告很长。 http://adtmag.com/articles/2000/03/16/comparing-floats-how-to-determine-if-floating-quantities-are-close-enough-once-a-tolerance-has-been.aspx

答案 5 :(得分:0)

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

我记得曾经存在于Seymour Cray设计的超级计算机中的错误 - 或者是怪癖。他的乘数只会将前12位检查为零,而加法器搜索13,留下一小部分可能为0比1的数字,但对另一个有有效数字。

William Kahan的一名学生正在使用IBM的360进行直升机转子的空气湍流模拟,当它首次推出其不寻常的32位fp格式时。 a - b未完全计算,即使这两个数字在彼此的两个因子之内,导致每次计算的准确性丢失的升级问题。因此,计算机给出了错误的结果。

Kahan让他的学生用双打重写他的代码,这产生了正确的失速点。