wgarvin wrote:Gerd Isenberg wrote:or with 0x88 squares ...
Code: Select all
int colorOfSquare (int x88square) {
return (0x00AA0055 >> x88square) & 1;
}
I think this code is actually non-portable... but it works on all of the x86 compilers, and probably on all other modern compilers.
I think bit shifts by more than the number of bits in the left operand are implementation-defined. The implementations all just use a single shift instruction, and x86 (and all other popular architectures, AFAIK) only look at the bottom N bits of the count operand to shift or rotate a 2^N bit number. I think the 8086 did not behave like this, but the 80286 and upwards did.
From ISO/IEC 9899:TC3 Committee Draft — Septermber 7, 2007 WG14/N1256
pages 84,85 section: Language §6.5.7
6.5.7 Bitwise shift operators
Syntax
1 shift-expression:
additive-expression
shift-expression << additive-expression
shift-expression >> additive-expression
Constraints
2 Each of the operands shall have integer type.
Semantics
3 The integer promotions are performed on each of the operands. The type of the result is that of the promoted left operand. If the value of the right operand is negative or is greater than or equal to the width of the promoted left operand, the behavior is undefined.
4 The result of E1 << E2 is E1 left-shifted E2 bit positions; vacated bits are filled with zeros. If E1 has an unsigned type, the value of the result is E1 ´ 2E2, reduced modulo one more than the maximum value representable in the result type. If E1 has a signed type and nonnegative value, and E1 ´ 2E2 is representable in the result type, then that is the resulting value; otherwise, the behavior is undefined.
5 The result of E1 >> E2 is E1 right-shifted E2 bit positions. If E1 has an unsigned type or if E1 has a signed type and a nonnegative value, the value of the result is the integral part of the quotient of E1 / 2E2. If E1 has a signed type and a negative value, the resulting value is implementation-defined.