Should you test an integer for evenness by n % 2 == 0 or n & 1 == 0? I always assumed they compiled down to the same thing, so today I checked. All code compiled in gcc4 -O3.
(gdb) x/8i foo1
0x1fa0 <foo1>: push %ebp
0x1fa1 <foo1+1>: mov %esp,%ebp
0x1fa3 <foo1+3>: mov 0x8(%ebp),%eax
0x1fa6 <foo1+6>: leave
0x1fa7 <foo1+7>: xor $0x1,%eax
0x1faa <foo1+10>: and $0x1,%eax
0x1fad <foo1+13>: ret
0x1fae <foo1+14>: xchg %ax,%ax
(gdb) x/8i foo2
0x1fb0 <foo2>: push %ebp
0x1fb1 <foo2+1>: mov %esp,%ebp
0x1fb3 <foo2+3>: mov 0x8(%ebp),%eax
0x1fb6 <foo2+6>: leave
0x1fb7 <foo2+7>: xor $0x1,%eax
0x1fba <foo2+10>: and $0x1,%eax
0x1fbd <foo2+13>: ret
0x1fbe <foo2+14>: xchg %ax,%ax
Yep, same thing. This worked the same with signed vs. unsigned ints on my intel mac. According to this thread, that isn’t the case on all architectures.
Premature optimizers should stop prematurely optimizing. If taking the remainder when divided by 2 is clearer to you, then do it that way. The compiler doesn’t care.
agreed about premature optimization. i have a feeling its mostly a result of legacy code/legacy code writers.
interesting though that the compiler managed to optimize the case for the zero equality test. I would have expected the int version of the test to be slightly longer handling the negative result case (i.e. int tmp = n&1; return (tmp<0?(tmp==0?0:(tmp|~1)):tmp);)
hm, n & 1 can only be either 0 or 1, right?
int x = -1;
x = x & 1;
printf(“%d\n”, x);
prints 1.
I was talking about the disassembly for:
int x = -1;
x = x % 2;
printf(“%d\n”,x);
should print -1.