If I ask java for:
System.out.print(-0.785 % (2*Math.PI));
And print the result, it shows -0.785 when it should be printing 5.498... Can anyone explain me why?
If I ask java for:
System.out.print(-0.785 % (2*Math.PI));
And print the result, it shows -0.785 when it should be printing 5.498... Can anyone explain me why?
The first operand is negative and the second operand is positive.
According to the JLS, Section 15.17.3:
[W]here neither an infinity, nor a zero, nor NaN is involved, the floating-point remainder r from the division of a dividend n by a divisor d is defined by the mathematical relation r = n - (d · q) where q is an integer that is negative only if n/d is negative and positive only if n/d is positive, and whose magnitude is as large as possible without exceeding the magnitude of the true mathematical quotient of n and d.
There is no requirement that the remainder is positive.
Here, n
is -0.785
, and d
is 2 * Math.PI
. The largest q
whose magnitude doesn't exceed the true mathematical quotient is 0. So...
r = n - (d * q) = -0.785 - (2 * Math.PI * 0) = -0.785
Ok, I'm not going to explain it better than the other answer, but let's just say how to get your desired results.
The function:
static double positiveRemainder(double n, double divisor)
{
if (n >= 0)
return n % divisor;
else
{
double val = divisor + (n % divisor);
if (val == divisor)
return 0;
else
return val;
}
}
What's happening:
If n >= 0
, we just do a standard remainder.
If n < 0
, we first do a remainder, putting it in the range (-divisor, 0]
, then we add divisor
, putting it in our desired range of (0, divisor]
. But wait, that range is wrong, it should be [0, divisor)
(5 + (-5 % 5)
is 5
, not 0
), so if the output would be divisor
, just return 0
instead.