1

想象一下我写了一个简单的计算器应用程序,它只计算简单的东西,比如

1.5 + 30 + 9755 - 30 - 20000 + 999900.54

我稍微记得使用浮点数时存在一些精度问题。我的计算器应用程序会在什么时候开始产生错误的结果?大多数时候,我只会计算像 1 + 2 - 963422 这样的整数,但有时我可能会输入一个浮点数。我对精度问题将在哪里开始生效没有什么大的线索。只是那双的最后一个数字?像-963419.0000000000003655?或者那会是什么样子?知道如何抓住这些吗?

4

6 回答 6

5

引用维基百科

除了失去显着性、无法准确表示 π 和 0.1 等数字以及其他轻微的不准确之外,还可能出现以下现象:

  • 取消:减去几乎相等的操作数可能会导致精度的极大损失。这可能是最常见和最严重的准确性问题。
  • 转换为整数并不直观:将 (63.0/9.0) 转换为整数会产生 7,但转换 (0.63/0.09) 可能会产生 6。这是因为转换通常会截断而不是舍入。地板和天花板函数可能会产生与直观预期值相差 1 的答案。
  • 有限的指数范围:结果可能溢出产生无穷大,或下溢产生次正规数或零。在这些情况下,精度将丢失。
  • 安全除法的测试是有问题的:检查除数不为零并不能保证除法不会溢出并产生无穷大。
  • 测试平等是有问题的。两个数学上相等的计算序列很可能产生不同的浮点值。程序员经常在一定的公差范围内进行比较(通常是一个十进制常量,它本身并不能准确表示),但这并不一定会让问题消失。

为了避免此类问题,您需要分析您的具体计算,以尽量减少错误传播

于 2009-08-16T16:40:22.100 回答
1

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

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

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

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

于 2009-08-16T14:57:41.273 回答
1

浮点数学充满了陷阱!这里有一些你应该注意的:

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

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

于 2009-08-16T16:15:03.097 回答
0

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

于 2009-08-17T11:54:46.557 回答
0

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

一些语言支持一个特殊的对象/结构来处理精确的十进制运算。Java 有 BigDecimal:http: //java.sun.com/javase/6/docs/api/java/math/BigDecimal.html

于 2009-08-16T15:28:54.143 回答
0

试试0.1 + 0.2 - 0.3

于 2009-08-16T16:24:01.797 回答