user1730056
user1730056

Reputation: 623

How can I remove a modulo out of my math operation?

My prof does not like the use of modulo since it's not efficient enough, but I'm not sure how else I can get the same answer using a logic operator or something. Can someone help me out with how I can do this?

j = (j + 1) % a.length;

Upvotes: 5

Views: 2108

Answers (4)

qaphla
qaphla

Reputation: 4733

The only way I can see of doing this without a modulo is still not great:

j = (++j < a.length)? j : (j - a.length);

Alternately, for more readability:

j++;
j = (j < a.length)? j : (j - a.length);

or

j++;
if (j >= a.length) {
    j -= a.length;
}

Also, I'm not entirely sure about how Java does with loop prediction, but at least in C, the following would be slightly better for speed, if less readable, since the general assumption is that the argument to the if statement will be true, and j < a.length more often than not (Unless a.length <= 2, which seems unlikely.)

j++;
if(j < a.length) {
}
else {
    j -= a.length;
}

If the initial value of j is outside the range 0 to a.length (inclusive-exclusive), then the only solutions either use a modulus or division, which, being the same operation, are the same speed, or a loop of subtraction, which will essentially accomplish the same thing as modulus on a very old processor, which is slower than the built in operation for modulus on any current processor I know about.

Upvotes: 3

Lee Meador
Lee Meador

Reputation: 12985

You could do this:

j = j + 1;
if (j >= a.length) {
    j = j - a.length; // assumes j was less than length before increment
}

@ajp suggests another solution that actually would work ok.

j = j + 1;
if (j >= a.length) { // assumes j was less than length before increment
    j = 0; 
}

If I was writing the code, id write it this way, just in case. It has very little additional overhead and removes the "assumes"

j = j + 1;
while (j >= a.length) {
    j = j - a.length;
}

Of course, the % would be a good way to do it too. Unless one is your professor.

This could be faster or slower than a divide/modulo depending on the cost of a jump (and any effect that has on the instruction pipeline/lookahead) and the efficiency of the integer division instructions.

Old processors would likely do better with the jump. More modern ones with the divide.

Upvotes: 2

RaptorDotCpp
RaptorDotCpp

Reputation: 1465

Think of what you are doing here. You are essentially saying:

if j + 1 is smaller than a.length, set j to j + 1
otherwise, we set j to a value smaller than a.length

This pseudocode should give you a very clear hint to the solution.

Upvotes: 1

Ankit Rustagi
Ankit Rustagi

Reputation: 5637

This should do the trick.

 int k = a.length;
 int d = (j+1)/k;
 j = (j+1) - d*k

Upvotes: 3

Related Questions