Run the code in Java
System.out.println (2.00-1.10);
The output results are: 0.8999999999999999
It's weird, not the value we're looking for 0.9.
Run the following code again:
System.out.println (2.00f-1.10f);
Output Result: 0.9
And rightly so, why does this cause this problem. Why do you try to avoid floating-point comparisons in your program?
In Java, the floating-point type is double, and 2.00 and 1.10 are converted to binary storage in the computer, which involves data precision, the reason for this phenomenon is precisely the problem of floating-point data precision. First understand the basics of float and double:
1. Float and double are the basic types of Java, used for floating-point representation, in Java, float 4 bytes 32 bits, a double for 8 bytes 64 bits, generally more suitable for engineering measurement calculations, its memory structure is as follows:
Float
Sign bit (1 bit) |
Index (8 bit) |
Mantissa (BIT) |
Double
Sign bit (1 bit) |
Index (one bit) |
Mantissa (BIT) |
Note: From left to right is from low to high, and within the computer is in reverse order storage.
2. System.out.println (2.00-1.10) 1.10 cannot be accurately stored by the computer, with the double type data 1.10 example how the computer converts floating-point data into binary storage.
Here the emphasis speaks of the decimal portion converted into binary:
1.10 The integer part is 1, converted to binary 1 (here the integer to binary system no longer repeat)
Fractional part: 0.1
0.1*2=0.2 the whole number of parts 0, Cardinal =0.2
0.2*2=0.4 the whole number of parts 0, Cardinal =0.4
0.4*2=0.8 the whole number of parts 0, Cardinal =0.8
0.8*2=1.6 the whole number of parts 1, Cardinal =1.6-1=0.6
0.6*2=1.2 the whole number of parts 1, Cardinal =1.2-1=0.2
0.2*2=0.4 the whole number of parts 0, Cardinal =0.4
.
.
.
.
Until the base is 0. 1.1 In binary notation: 1.000110...xxxx .... (omitted later)
0.1 = 0*2^ (-1) +0*2^ (-2) +0*2^ (-3) +1*2^ (-4) + ..... The double type indicates that the decimal part is only 52 digits, and when the cardinality is not 0 after the 52-bit backwards, the remainder can only be discarded, from where you can see that float and double do not accurately represent each decimal, and that some decimal places can only be infinitely inclined to it. In the computer, the addition and subtraction of the operation is actually finally converted into a binary addition operation in the computer, thus, when the computer runs System.out.println (2.00-1.10);
The binary representation in the computer's memory is computed, and the 1.10 binary representation itself is inaccurate, so a 0.8999999999999999 result appears.
But why System.out.println (2.00f-1.10f); The result is 0.9. Because the float precision is not as large as the double precision, the decimal part of the 0.1 binary indicates that there are many more.
Note: In the program should try to avoid floating point of comparison float, double type of operations are often inaccurate
Workaround:
Use the method provided by BigDecimal to perform comparisons or operations, but be careful to construct BigDecimal using a float, double string, BigDecimal (string val Why not write more clearly in the BigDecimal (double Val) API.
The operation takes the subtraction as an example:
BigDecimal B1 = new BigDecimal (double.tostring (2.00));
BigDecimal b2 = new BigDecimal (double.tostring (1.10));
Double result = B1.subtract (B2). Doublevalue ();