在使用双值计算时,我什么时候会遇到问题?

时间:2009-08-16 14:31:46

标签: iphone math precision

想象一下,我编写了一个简单的计算器应用程序,它只计算像

这样的简单东西
  

1.5 + 30 + 9755 - 30 - 20000 + 999900.54

我稍微记得使用浮点数时存在一些精度问题。我的计算器应用程序会在哪个时候开始创建错误的结果?大多数时候,我只计算1 + 2 - 963422之类的整数,但有时候我可能会输入一个浮点数。关于精度问题何处开始生效,我一无所知。这个双倍的最后一个数字?像-963419.0000000000003655?或者看起来怎么样?任何想法如何抓住那些?

6 个答案:

答案 0 :(得分:5)

引用Wikipedia

  

除了失去意义外,   无法表示诸如此类的数字   π和0.1完全相同,其他轻微   不准确,有以下现象   可能会发生:

     
      
  • 取消:减去几乎相等的操作数可能会造成极大的损失   准确性。这可能是最多的   常见且严重的准确性问题。
  •   
  • 转换为整数并不直观:将(63.0 / 9.0)转换为   整数产生7,但转换   (0.63 / 0.09)可能会产生6.这是   因为转换通常会截断   而不是圆形。地板和天花板   函数可以产生答案   从直觉上脱离一个人   期望值。
  •   
  • 有限指数范围:结果可能溢出,产生无穷大,或   下溢产生一个次正规数   或零。在这些情况下精确度会   迷路了。
  •   
  • 安全划分的测试存在问题:检查除数   不是零不保证一个   分裂不会溢出和屈服   无穷大。
  •   
  • 测试平等是有问题的。两个计算   数学上的序列   平等可能产生不同   浮点值。程序员   经常在一些内部进行比较   公差(通常为十进制常数,   本身没有准确表示),   但这并不一定能成功   问题消失了。
  •   

为了避免此类问题,您需要分析您的具体计算,以便最大限度地减少error propagation

答案 1 :(得分:1)

浮点精度“问题”始终存在于每个浮点计算中。

有时,你很幸运,并且正在使用仅涉及2:x.25,y.125等幂的数字。小数点右边的部分是1 /(2 ^ k )任何整数, k

如果使用小数位不是2的幂的任何值,则表示存在问题。 1./3。,1. / 5。,1. / 6。,1. / 7。,1. / 9。等。

所有非2次幂值都会出现浮点表示问题。

答案 2 :(得分:1)

浮点数学充满了陷阱!以下是您应该注意的一些内容:

1)添加非常大且非常小(绝对值)的数字。 IEEE-754单精度浮点数具有大约7个有效十进制精度数。所以,如果你尝试 要计算1000000.0 + 3.14159,您将丢失小数点后的大部分数字。 如果使用朴素算法计算大型数组的运行总和,则会发生这种情况 (数百万的小值)。要查看更好的方法,请查看Kahan summation

2)减去两个大的,几乎相等的数字存在类似的问题。结果可能只有一个或两个有效数字。同样,解决方案通常是以避免“减去两只大象以获得鼠标”的方式重新安排计算。

答案 3 :(得分:0)

很难说“何时”,这取决于你的数字有多大/多小,你做了多少操作,以及你需要多少精度。

某些语言支持处理精确小数运算的特殊对象/构造。 Java有BigDecimal:http://java.sun.com/javase/6/docs/api/java/math/BigDecimal.html

答案 4 :(得分:0)

尝试0.1 + 0.2 - 0.3

答案 5 :(得分:0)

对于一个实际示例,在IEEE754 32位(单精度)浮点中,整数最多只能表示为16777216,高于存在间隙。 16777216之后的下一个浮点数是16777218。