Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Modulo of negative numbers [duplicate]

Tags:

Possible Duplicate:
Mod of negative number is melting my brain!

I was wondering if there was a nicer algorithm for what I'm trying to do:

 wrapIndex(-6, 3) = 0 wrapIndex(-5, 3) = 1 wrapIndex(-4, 3) = 2 wrapIndex(-3, 3) = 0 wrapIndex(-2, 3) = 1 wrapIndex(-1, 3) = 2 wrapIndex(0, 3) = 0 wrapIndex(1, 3) = 1 wrapIndex(2, 3) = 2 wrapIndex(3, 3) = 0 wrapIndex(4, 3) = 1 wrapIndex(5, 3) = 2 

I came up with

 function wrapIndex(i, i_max) {         if(i > -1)             return i%i_max;          var x = i_max + i%i_max;         if(x == i_max)             return 0;          return x;     } 

Is there a nicer way to do this?

like image 253
fresskoma Avatar asked Aug 05 '10 17:08

fresskoma


1 Answers

This solution is branchless, but performs % twice:

function wrapIndex(i, i_max) {    return ((i % i_max) + i_max) % i_max; } 

It should be said the C#/Java behavior of % is assumed, i.e. the result has the same sign as the dividend. Some languages define the remainder calculation to take the sign of the divisor instead (e.g. mod in Clojure). Some languages have both variants (mod/rem pair in Common Lisp, Haskell, etc). Algol-68 has %x which always returns a non-negative number. C++ left it up to implementation until C++11, now the sign of the remainder is (almost) fully specified according to the dividend sign.

See also

  • Wikipedia/Modulo operation
like image 180
polygenelubricants Avatar answered Sep 25 '22 12:09

polygenelubricants