Modulo does not work

I know this will seem like a really stupid question, but I just don't understand why this is not working. It:

System.out.println(5 % .10); 

And he returns:

 0.09999999999999973 

I really have no IDEA. I am just learning Java and I am very familiar with C #, so I tried with C #. C # seemed to return the same thing too.

+6
source share
5 answers

As others have explained, this is due to inaccuracies caused by floating point precision.

You must use BigDecimal , in this case the remainder method for exact decimal arithmetic.

 BigDecimal number = new BigDecimal(5); BigDecimal divisor = new BigDecimal("0.1"); BigDecimal result = number.remainder(divisor); System.out.println(result); // 0 
+8
source

This is due to floating point precision. 0.10 cannot be represented exactly in binary format. Therefore, the result is not exactly 0.10 and therefore does not change to 0 .

This will work with 0.25 because 0.25 can be represented exactly in binary format.

EDIT:

In general, any number that can be expressed as a fraction with a force of two in the denominator can be precisely expressed in IEEE floating point. (provided that it is not crowded)

+8
source

You are doing floating point arithmetic. 0.1 does not have an exact representation as a float.

+2
source

Java (like most programming languages ​​except COBOL) performs calculations on binary systems. I think 0.10 has such a bad binary representation that the result of your calculations looks like this. I think it is better to avoid calculating the double or float module and stick to the whole or long result to get the best results.

+1
source

The binary representation for 0.1 is

 System.out.println(new BigDecimal(0.1)); 

prints

 0.1000000000000000055511151231257827021181583404541015625 

When you type 0.1, you get a small amount of rounding that hides this error.

When you do the calculation, you should use BigDecimal to either round the result or transform the calculations to minimize the error.

 5 % 0.1 (5 / 0.1 % 1) * 0.1 50 % 1 / 10 

In terms of double you can do

 double d = 5; double mod0_1 = d * 10 % 1 / 10; double rounded = Math.round(mod0_1 * 1e12)/1e12; // round to 12 places. 

Note: the result may still have a small error, but it will be small enough that you will not see it when printing it.

+1
source

Source: https://habr.com/ru/post/898114/


All Articles