Modulo doesn't work
I know this will seem like a really stupid question, but I just don't get why this isn't working. This:
System.out.println(5 % .10);
And it's returning:
0.09999999999999973
I really have NO IDEA. I'm just learning Java, and I'm pretty good with C#, so I tried with C# to. C# 开发者_如何学Goseemed to return the same thing also.
As others explained, this is due to inaccuracies caused by floating point precision.
You should use BigDecimal, in this case the remainder method for precise arithmetic involving decimals.
BigDecimal number = new BigDecimal(5);
BigDecimal divisor = new BigDecimal("0.1");
BigDecimal result = number.remainder(divisor);
System.out.println(result); // 0
This is due to floating-point precision. 0.10
cannot be represented exactly in binary. Therefore the result is not exactly 0.10
and is hence not modded down to 0
.
This will work with 0.25
because 0.25
can be represented exactly in binary.
EDIT:
In general, any number that can be expressed as a fraction with a power-of-two in the denominator can be expressed exactly in IEEE floating-point. (provided it doesn't over/underflow)
You're doing floating point arithmetic. 0.1 has no exact representation as a float.
Java (like most programming languages except COBOL) is making computations in the binary systems. I think 0.10 has such a unlucky binary representation that the result of your computation looks like this. I think it is best to avoid computing modulus of double or float and stick to integer or long to get better results.
The binary representation for 0.1 is
System.out.println(new BigDecimal(0.1));
prints
0.1000000000000000055511151231257827021181583404541015625
When you print 0.1, you get a small amount of rounding which hides this error.
When you perform a calculation you have to use BigDecimal or round the result or transform the calculation to minimise 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 can still have a slight error, but it will be small enough that when you print it, you won't see it.
精彩评论