想象一下,我编写了一个简单的计算器应用程序,它只计算像
这样的简单东西1.5 + 30 + 9755 - 30 - 20000 + 999900.54
我稍微记得使用浮点数时存在一些精度问题。我的计算器应用程序会在哪个时候开始创建错误的结果?大多数时候,我只计算1 + 2 - 963422之类的整数,但有时候我可能会输入一个浮点数。关于精度问题何处开始生效,我一无所知。这个双倍的最后一个数字?像-963419.0000000000003655?或者看起来怎么样?任何想法如何抓住那些?
答案 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。