-2

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?

Xkynar
  • 935
  • 1
  • 10
  • 31
  • Why should it be printing that? Calc.exe tells me `-0.785` as well. `2 * pi` = `6.28`. `6.28` is bigger than `-0.785`, thus it will mod the entire first argument. – Jeroen Vannevel Sep 24 '13 at 23:50
  • 1
    Why do you expect 5.498? The remainder of 0.785 when dividing my anything larger than 0.785 will be exactly 0.785 – sashkello Sep 24 '13 at 23:50
  • @sashkello Well, the linked question asks about C, not Java. (thought the concept is the same, i admit) – Dennis Meng Sep 24 '13 at 23:53
  • Please see the link above. There are two possible ways of finding remainder here. Java thinks of it as -(0.785%(2*pi)) – sashkello Sep 24 '13 at 23:53
  • if i write -0.785 % (2*PI) on google's calculator it tells me 5.498 and its also the radian value corresponding to the same math in degrees, that is, -45 % 360 = 315 and 315 degrees to radians is 5.498 – Xkynar Sep 24 '13 at 23:53
  • 1
    @DennisMeng Well, the underlying issue is the maths, which is not specific to the language. – Bernhard Barker Sep 24 '13 at 23:54
  • @Dukeling Sure. I just figure that there's a previous question that specifically asks about Java modulo, and may as well mark as duplicate of *that*. – Dennis Meng Sep 24 '13 at 23:55
  • 1
    You mean this one? http://stackoverflow.com/questions/4403542/how-does-java-do-modulus-calculations-with-negative-numbers Didn't see it initially... The C question has much better answers, it's in my favourites :) – sashkello Sep 24 '13 at 23:56
  • @DennisMeng Finding the best duplicate can take a bit of work, so just finding an acceptable one is usually done, especially since we don't get any reward for doing this. – Bernhard Barker Sep 24 '13 at 23:57
  • @Dukeling fair enough – Dennis Meng Sep 24 '13 at 23:57
  • @sashkello Yeah, that looks about right. – Dennis Meng Sep 24 '13 at 23:58

2 Answers2

3

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
rgettman
  • 176,041
  • 30
  • 275
  • 357
1

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.

Community
  • 1
  • 1
Bernhard Barker
  • 54,589
  • 14
  • 104
  • 138
  • Thank you alot, Id love to accept your answer as the right one since it was the only one which actually solved my problem but the above answer is the one which actually answers my question :( +1 though :) – Xkynar Sep 25 '13 at 00:09