It's not the same. Try num = -79
, and you will get different results from both operations. (-79) % 256 = -79
, while (-79) & 0xff
is some positive number.
Using unsigned int
, the operations are the same, and the code will likely be the same.
PS- Someone commented
They shouldn't be the same,
a % b
is defined asa - b * floor (a / b)
.
That's not how it is defined in C, C++, Objective-C (ie all the languages where the code in the question would compile).
-1 % 256
yields -1
and not 255
which is -1 & 0xFF
. Therefore, the optimization would be incorrect.
C++ has the convention that (a/b)*b + a%b == a
, which seems quite natural. a/b
always returns the arithmetic result without the fractional part (truncating towards 0). As a consequence, a%b
has the same sign as a
or is 0.
The division -1/256
yields 0
and hence -1%256
must be -1
in order to satisfy the above condition ((-1%256)*256 + -1%256 == -1
). This is obviously different from -1&0xFF
which is 0xFF
. Therefore, the compiler cannot optimize the way you want.
The relevant section in the C++ standard [expr.mul §4] as of N4606 states:
For integral operands the
/
operator yields the algebraic quotient with any fractional part discarded; if the quotienta/b
is representable in the type of the result,(a/b)*b + a%b
is equal toa
[...].
However, using unsigned
types, the optimization would be completely correct, satisfying the above convention:
unsigned(-1)%256 == 0xFF
See also this.
This is handled very different across different programming languages as you can look up on Wikipedia.
Since C++11, num % 256
has to be non-positive if num
is negative.
So the bit pattern would depend on the implementation of signed types on your system: for a negative first argument, the result is not the extraction of the least significant 8 bits.
It would be a different matter if num
in your case was unsigned
: these days I'd almost expect a compiler to make the optimisation that you cite.
I don't have telepathic insight into the compiler's reasoning, but in the case of %
there is the necessity of dealing with negative values (and division rounds towards zero), while with &
the result is always the lower 8 bits.
The sar
instruction sounds to me like "shift arithmetic right", filling up the vacated bits with the sign bit value.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With