質問

When executing the following code:

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);
    }
}

The following output is displayed:

1.0000001

But output should be 1.0000000, right? Correct me if I'm wrong..!!

役に立ちましたか?

解決

0.1 is not really "0.1" with IEEE 754 Standard.

0.1 is coded : 0 01111011 10011001100110011001101 (with float number)

  • 0 is the sign (= positive)
  • 01111011 the exponent (= 123 -> 123 - 127 = -4 (127 is the bias in IEEE 754))
  • 10011001100110011001101 the mantissa

To convert the mantissa in decimal number we have 1.10011001100110011001101*2^-4(base2) [the 1.xxx is implicit in 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)

他のヒント

Much like certain real numbers like 1/3 cannot be expressed exactly in our decimal system certain numbers like 1/10 cannot be exactly expressed in in binary.

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

Because we are so familiar with decimal it seems obvious that 1/3 cannot be exactly represented, but to someone with a base 3 number system this would seem like a major limitation to decimal;

1/3=(base 3)0.1

As such 1/10 is inexactly represented within the float and by adding multiple inexact numbers together you get an inexact answer.

It is within this context that you should interpret the floating point errors. If you have a number that is exactly representable within decimal but not within binary then you may find BigDecimal useful. But you should not consider BigDecimal to be better than floating point numbers; it just has a different set of numbers it can and can't represent exactly; the set you're used to. BigDecimal also attempts to use the decimal counting system on a binary processor; as such its calculations are less efficient that double/float based calculations

If you need exact computation, like when you work with very sensitive data, don't use float or double, their representation in binary uses approximations. Check this article for some nice explanations.

It is a common misunderstanding. This kind of "errors" are related with floating point data structures: read this. You can use a double in this case to get more precision.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top