2

I'm almost embarrased to ask this, because it's probably VERY obvious - but I can't see a way out of this neatly and suspect there is one.

I have a variable which I need to add/subtract values from - but I want to keep it within a range of values, looping around at either end - e.g.

Range is 0-3 so values are 0,1,2,3,0,1,2,3 - and this does that

x = (x + val) MOD 4

When val is negative, however, we should see 0,3,2,1,0,3,2,1 and the solution is FAR less elegant

x = (x + val) MOD 4
if (x < 0) x = 4 + x;

That works, but it's clunky and I can't help thinking there might be a 'one line' solution to this - but I'm damned if I can think of it? :)

prepares for embarrassment

  • 1
    Why does it have to be one line long? – Raedwald Oct 17 '12 at 12:35
  • The proper modulus operator already does this. If you implement this using the remainder operator (commonly `%` in programming languages) then the behaviour changes with negative numbers and you need the two-liner that you posted. In other words: you probably used the remainder operator instead of the proper modulus operator. – TaZ Oct 17 '12 at 12:55
  • @raedwald it could be 50 lines if it were elegant and look and feel like a bodge :) –  Oct 17 '12 at 13:12
  • Possible duplicate: http://stackoverflow.com/questions/9284644/why-is-operator-referred-to-as-the-modulus-operator-instead-of-the-remainder – Rody Oldenhuis Oct 17 '12 at 13:16
  • @TaZ aha - now I realise this isn't an uncommon question and that how languages approach Modulus varies wildly (and the suggestion appears to be that neither approach is 'right' - you just have to work around it...)!? –  Oct 17 '12 at 13:16
  • @Rody Oldenhuis - and many other questions now I realise that Modulus doesn't have a fixed behaviour with negative results... –  Oct 17 '12 at 13:17
  • So, not a silly question after all :) – Rody Oldenhuis Oct 17 '12 at 13:19
  • This question actually has a devastatingly simple answer which I'm frantically checking works -http://stackoverflow.com/questions/4412179/best-way-to-make-javas-modulus-behave-like-it-should-with-negative-numbers - and it seems to...! –  Oct 17 '12 at 13:19
  • Difficult to choose an answer to this - TaZ determined the problem, Rody outlined one solution and the question I linked contains a specific solution which works in Javascript (which is what I'm using tho I didn't mention that!) - hmmmmm.... –  Oct 17 '12 at 18:33

1 Answers1

2

As indicated by TaZ, most "modulo" operators are really remainder operators that only work like a "mathematical modulo" for x+val >= 0.

In c++, as found here (with some modifications), you can define a more "mathematically correct" modulo like so

double mod(double x, double y) { return y!=0 ? x-floor(x/y)*y : x; }   

(perhaps also make an integer version), such that

x = mod(x+val,4); 

works for both positive and negative x+val.

Rody Oldenhuis
  • 37,726
  • 7
  • 50
  • 96
  • My particular need is with Javascript - and the question I quoted in comments earlier suggests... ((a+b)%a+b)%b which is really elegant but I'm scribbling on notepads to check it :) –  Oct 17 '12 at 13:24