Question

Here is some example code

int test = 1234;
int modValue, andValue;
modValue = test % -8;
andValue = test & 7;
printf("Mod Value = %d And Value = %d\n", modValue, andValue);

int counter = 0;
for(counter = 0; counter < 10000; counter++) {
    modValue = counter % -8;
    andValue = counter & 7;
    if(modValue != andValue) {
        printf("diff found at %d\n", counter);
    }
}

Ideone link: http://ideone.com/g79yQm

Negative numbers give different results, that's about it but other then that do they always both function exactly the same for all positive values?

Even for negative numbers they seem to be offsetted only always just off by 1 cyclic round.

Those wondering it's similar to this question Why is modulo operator necessary? question but I don't subtract 1.

This uses negative values which are higher then the modulus value and yeah only works for positive values.

I found this from the IDA-PRO Hex-Ray's decompiler seems to generate sometimes a Modulus % and other times a AND & operator for both identical source codes afaik in different functions. I guess it's from the optimizer.

Since this project I decompiled shouldn't even use negative values I wonder what was the original source code doubt anyone uses modulus with negative values though seems weird.

Also using And as a modulus command how I know cyclic operation always use a modulus yet in this case the person must of used a Val And 7 since Val % 7 is completely different result.

Forgot to say the original code most likely used abs(Val) and 7 since anything with modulus with positive values seems to be wrong I don't think anyone would be using modulus with negative values it looks unappealing to the eyes. So I guess that's the best it could be.

Was it helpful?

Solution

The optimization of x % N to x & (N-1) only works if N is a power of two.

You also need to know that x is positive, otherwise there is a little difference between the bitmask operation and the remainder operation. The bitmask operation produces the remainder for the Euclidean division, which is always positive, whereas % produces the remainder for C's division /, which rounds towards zero and produces a remainder that is sometimes negative.

OTHER TIPS

The sign of the result of % are machine dependent for negative operands, the same applies for overflow/underflow. / by proxy follows the same rules.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top