浮点加法 - 给出奇怪的结果..!

时间:2013-09-30 06:48:42

标签: java floating-point floating-accuracy

执行以下代码时:

public class FPoint {
    public static void main(String[] args) {
        float f = 0.1f;
        for(int i = 0; i<9; i++) {
            f += 0.1f;
        }
        System.out.println(f);
    }
}

显示以下输出:

1.0000001

但输出应该 1.0000000 ,对吗?如果我错了,请纠正我...... !!

4 个答案:

答案 0 :(得分:7)

对于IEEE 754标准,

0.1实际上并非“0.1”。

0.1编码:0 01111011 10011001100110011001101(带浮点数)

  • 0是符号(=正数)
  • 01111011指数(= 123 - > 123 - 127 = -4 (127是IEEE 754中偏差))
  • 10011001100110011001101尾数

要转换十进制数的尾数,我们有 1.10011001100110011001101 * 2 ^ -4 (base2)[1.xxx隐含在IEEE 754中]

= 0.000110011001100110011001101(base2)

= 1/2 ^ 4 + 1/2 ^ 5 + 1/2 ^ 8 + 1/2 ^ 9 + 1/2 ^ 12 + 1/2 ^ 13 + 1/2 ^ 16 + 1/2 ^ 17 + 1 ^ 2 ^ 20 + 1/2 ^ 21 + 1/2 ^ 24 + 1/2 ^ 25 + 1/2 ^ 27(base10)

= 1/16 + 1/32 + 1/256 + 1/512 + 1/4096 + 1/8192 + 1/65536 + 1/131072 ......(base10)

= 0.10000000149011612 (base10)

答案 1 :(得分:4)

就像我们的十进制系统中的某些实数(如1/3)无法准确表达一样,某些数字(如1/10)无法用二进制表示。

1/3=(decimal)0.33333333333 (3) recurring  
1/10=(binary)0.00011001100 (1100) recurring 

因为我们对小数非常熟悉,所以很明显1/3无法准确表示,但对于具有基数为3的系统的人来说,这似乎是对小数的一个主要限制;

1/3=(base 3)0.1

因为这样的1/10在浮点数中不精确地表示,并且通过将多个不精确的数字加在一起,你会得到一个不准确的答案。

在此上下文中,您应该解释浮点错误。如果您有一个在十进制内可以完全表示但不在二进制内的数字,那么您可能会发现BigDecimal很有用。但是你不应该认为BigDecimal比浮点数更好;它只是有一组不同的数字,它不能完全代表;你习惯的那套。 BigDecimal还尝试在二进制处理器上使用十进制计数系统;因此,它的计算效率低于基于双/浮点的计算

答案 2 :(得分:0)

如果您需要精确计算,例如处理非常敏感的数据时,请不要使用floatdouble,它们在二进制中的表示使用近似值。请查看此article以获得一些不错的解释。

答案 3 :(得分:-1)

这是一种常见的误解。这种“错误”与浮点数据结构有关:读this。在这种情况下,您可以使用double来获得更高的精确度。