Comparison and use of double and float in Java

Run the code in java

System.out.println(2.00-1.10); The
output result is: 0.8999999999999999
is very strange, not the value 0.9 we want

Then run the following code:
System.out.println(2.00f-1.10f);
output result: 0.9

It's correct again. Why does this cause this problem? Why should we try to avoid comparison of floating-point numbers in the program?

The default floating point type in Java is double, and 2.00 and 1.10 must be converted to binary storage in the computer, which involves data accuracy. The reason for this phenomenon is the accuracy of floating point data. First understand the basic knowledge of float and double:

  1. Float and double are the basic types of Java, used for floating-point number representation. In Java, float occupies 4 bytes and 32 bits, and double occupies 8 bytes and 64 bits. Generally, they are more suitable for engineering measurement calculations. They are in memory. The storage structure is as follows:

float:

Sign bit (1 bit)
Exponent (8 bit)
mantissa (23 bit)
double:

Sign bit (1 bit)
Exponent (11 bit)
Mantissa (52 bit)

Note: From left to right is from low to high, and the computer is stored in reverse order.

  1. System.out.println(2.00-1.10); 1.10 cannot be accurately stored by the computer. Take double type data 1.10 as an example of how a computer converts floating-point data into binary storage.
    Here, the focus is on converting the decimal part into binary:
    1.10 Integer part It is 1, converted to binary 1 (here integer to binary is not repeated here)
    decimal part: 0.1
    0.1 2=0.2 takes the integer part 0, base=0.2
    0.2
    2=0.4 takes the integer part 0, base=0.4
    0.4 2=0.8 takes the integer Part 0, base=0.8
    0.8
    2=1.6 take integer part 1, base=1.6-1=0.6
    0.6 2=1.2 take integer part 1, base=1.2-1=0.2
    0.2
    2=0.4 take integer part 0, base=0.4
    .
    .
    .
    .
    up to binary radix 0.1.1 expressed as: 1.000110 ... xxxx ... (omitted expressed later)
    0.1 0 = 2 (-1) 0 + 2 * (-2) + 0 2 (-3) + 1 * 2(-4)+...and the double type means that the decimal part has only 52 digits. When the base number is not 0 after 52 digits are calculated backward, the latter part can only be discarded. From this we can see that float and double cannot accurately represent each One decimal place, for some decimals, it can only tend to it infinitely. In the computer, addition, subtraction and division operations are actually converted into binary addition operations in the computer. Therefore, when the computer runs System.out.println(2.00-1.10);
    it will take their binary in the computer memory. Represents calculation, and the binary representation of 1.10 is not accurate, so a result of 0.8999999999999999 will appear.

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 0.1 binary representation is more often discarded.

note:

The program should try to avoid the comparison of floating-point numbers.
The operations of float and double types are often inaccurate.
Solution:

Use the methods provided by BigDecimal for comparison or operation, but pay attention to the use of float and double string construction when constructing BigDecimal, BigDecimal(String val); why not write in BigDecimal(double val) API for clearer.

Take 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();

Guess you like

Origin blog.csdn.net/weixin_38019299/article/details/103189209