Home > Article > Backend Development > Why Does 1 >> 32 Result in 1, But 1 (uint64_t) >> 32 Result in 0?
> 32 Result in 1, But 1 (uint64_t) >> 32 Result in 0? " />
Problem:
In a C program, the right shift operator exhibits strange behavior:
<code class="cpp">int foo(int a, int b) { return a >> b; } int main() { std::cout << "foo(1, 32): " << foo(1, 32) << std::endl; }
The output is 1, which is unexpected since the result should theoretically be 0. Moreover, the behavior differs based on the argument types:
<code class="cpp">int bar(uint64_t a, int b) { return a >> b; } std::cout << "bar(1, 32): " << bar(1, 32) << std::endl; // Outputs 0
Explanation:
This behavior stems from the fact that the right shift operator works differently depending on the width of the underlying data type. For 32-bit integers (int in this case), the right shift is a "logical" shift, meaning it fills the vacated bits with zeros irrespective of the value of b. Therefore, 1 >> 32 evaluates to 1, as shifting by more than the number of bits has no effect.
However, for 64-bit integers (uint64_t), the right shift is an "arithmetic" shift, meaning it fills the vacated bits with the same sign bit as the operand. Since the value 1 has a positive sign bit, the result of 1 >> 32 is 0.
Compiler Optimization:
Additionally, the compiler's optimization plays a role. The expression 1 >> 32 is a compile-time constant, which allows the compiler to fold it into 0 during compilation. This differs from the dynamic evaluation of foo(1, 32) within the function.
Portability Issue:
It's crucial to note that this behavior is architecture-dependent. On some architectures, like ARM, the logical right shift is implemented differently than on x86/x86-64 CPUs. As a result, shifting a 32-bit integer by a value greater than or equal to 32 may produce non-portable results.
The above is the detailed content of Why Does 1 >> 32 Result in 1, But 1 (uint64_t) >> 32 Result in 0?. For more information, please follow other related articles on the PHP Chinese website!