Thanks for clarifying that. This discussion arose from a question by Bob if shifts by zero is legitimate in my code. In the case of my code:wgarvin wrote:Edsel Apostol wrote: What I mean if that is still undefined in the C standard. I already knew that anything^0 = 1 in my algebra class since I'm 13 years old.
If one we're to base on this deductions, if anything^0=1 is defined in the C standard, therefore a shift by 0 will still produce the same number being shifted. So there is no undefined behavior in it. If there will be problems with other hardware concerning this, it must be the problem of the hardware itself and not in the code.They were pretty careful with the definitions. They standardized everything that was predictable across real hardware (of that era) and avoided specifying behaviours for things that have different behaviour on different hardware (shifting by greater or equal to the number of bits in a word, 1s- and 2s-complement machines, etc.)The authors of the C standard wrote: 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 * 2^E2, reduced modulo one more than the maximum value representable in the result type. If E1 has a signed type and nonnegative value, and E1 * 2^E2 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.
"The result of E1 << E2 is E1 left-shifted E2 bit positions". If E2 is zero, it is left-shifted by zero bit positions, and there are no vacated bits to fill.
"The result of E1 >> E2 is E1 right-shifted E2 bit positions." Same thing, except that it is implementation-defined if E1 has a signed type and a negative value. Which means it has to do something consistent for your implementation, but the standard does not specify what. In practice, every implementation you'll ever come across leaves the value of E1 unchanged if E2 is zero (because it is what the underlying shift and rotate instructions do, at least on every platform I've ever heard of).
When this standard was written, they had to contend with 1s-complement math and byte- and word-sizes that were not multiples of 8 bits. We are spoiled nowadays: Every machine made in at least the last 20 years has IEEE floats, 2's complement integers, 8-bits to a byte, and 16 or 32 or 64 bits to a word.
Code: Select all
return score & ~((1<<grain)-1);