Why floating-point numbers can sometimes be accurately represented in JAVA

set double = 0.1 in java, and then print it out, which is still 0.1. However, according to the binary floating-point number representation, it should not accurately represent 0.1, but can only accurately represent numbers such as 0.5 and 0.25. I want to know how JAVA can accurately represent floating point numbers in some cases.

give another example, 0.4 code , while 0.4-0.3cm 0.100000000000003 .

Sep.10,2021

I happen to have done a little research.

first of all, it is certain that this phenomenon does not occur in the presentation phase of binary numbers, and there is no doubt that 0.1 cannot be accurately represented by binary floating-point numbers.

The reason why

appears that floating-point numbers that cannot be accurately represented are accurate when printed out, because Java is a little clever in the process of converting them to strings. It converts a floating-point number that looks suspected to be an "whole" to the decimal form of that "whole".

for example, 0.1, if converted directly according to the internal representation, it may be 0.1000.0011. In this case, if the values of the last two digits are too small, Java will think that the precision is not enough, so when converted to a string, it will be converted to 0.1.

and 0.4 shock 4 and 0.4-0.3, because there is at least one number that cannot be accurately expressed when participating in the calculation, so the results may have some errors. According to the previous example, the result of 0.4 hand 4 may be 0.1000.0010, the last bit is different from the real 0.1, while the result of 0.4-0.3 is 0.1000.0300, this error is larger.

Note: the above values are only my imaginary values, not real data. It only needs to be able to explain the problem.

because of the difference between the two errors, the result of 0.4 ram 4 will still be regarded as the decimal 0.1 of "whole", but 0.4-0.3 is not considered to be 0.1 but converted to 0.1000.03 because of the large cumulative error.


@ Code Universe has answered part of it. I add some of my own understanding.

  1. when declaring double=0.1 , it is theoretically impossible to declare this, because there is no 0.1 in floating-point numbers. But the compiler can't just report an error, so the compiler converts 0.1 to a floating-point number closest to 0.1.
  2. when printing java decimals, we can find a phenomenon, that is, the printing accuracy is the same, all 16 digits. For example:

     
    

    even the decimal system has floating-point numbers that cannot be accurately represented, for example, 1Universe 3. How do you express it in binary? However, everything such as 1Accord 10, 10, 10, 10, 10, 10, and 100 can be accurately represented in decimal system, so it can be accurately represented in binary system, such as 1, 2, 2, 1, 4, 4, 8, 8, 3, 8, 8, 8, and so on.

    Java represents floating point numbers precisely through Decimal and BigDecimal classes.

    For more information on how double and float are stored, please refer to the IEEE 754 standard.

Menu