Note that there are some explanatory texts on larger screens.

plurals
  1. POWhy use only the lower five bits of the shift operand when shifting a 32-bit value? (e.g. (UInt32)1 << 33 == 2)
    primarykey
    data
    text
    <p>Consider the following code:</p> <pre><code>UInt32 val = 1; UInt32 shift31 = val &lt;&lt; 31; // shift31 == 0x80000000 UInt32 shift32 = val &lt;&lt; 32; // shift32 == 0x00000001 UInt32 shift33 = val &lt;&lt; 33; // shift33 == 0x00000002 UInt32 shift33a = (UInt32)((UInt64)val &lt;&lt; 33); // shift33a == 0x00000000 </code></pre> <p>It doesn't generate a warning (about using a shift greater than 32) so it must be an expected behavior.</p> <p>The code that actually gets put out to the generated assembly (or at least Reflector's interpretation of the code) is</p> <pre><code> uint val = 1; uint shift31 = val &lt;&lt; 0x1f; uint shift32 = val; uint shift33 = val &lt;&lt; 1; uint shift33a = val &lt;&lt; 0x21; </code></pre> <p>The IL (again, using Reflector) is</p> <pre><code>L_0000: nop L_0001: ldc.i4.1 L_0002: stloc.0 L_0003: ldloc.0 L_0004: ldc.i4.s 0x1f L_0006: shl L_0007: stloc.1 L_0008: ldloc.0 L_0009: stloc.2 L_000a: ldloc.0 L_000b: ldc.i4.1 L_000c: shl L_000d: stloc.3 L_000e: ldloc.0 L_000f: conv.u8 L_0010: ldc.i4.s 0x21 L_0012: shl L_0013: conv.u4 L_0014: stloc.s shift33a </code></pre> <p>I understand <strong>what</strong> is going on (it's described in <a href="http://msdn.microsoft.com/en-us/library/aa691377.aspx" rel="noreferrer">MSDN</a>); when the code is compiled, only the lower 5 bits are being used when shifting a 32-bit value... I'm curious as to <strong>why</strong> this happens. </p> <p>(The way <code>shift33a</code> comes out also makes me think that something isn't quite right with Reflector, as their c# presentation of the IL will compile to something different)</p> <p><strong>The question(s):</strong></p> <ul> <li><strong>Why</strong> are only the lower 5 bits of "the value to shift by" used? </li> <li>If "it doesn't make sense to shift more than 31 bits", why isn't there a warning?</li> <li>Is this a backwards compatilbility thing (i.e. is this what programmers "expect" to happen)?</li> <li>Am I correct that the underlying IL can do shifts of more than 31 bits (as in <code>L_0010: ldc.i4.s 0x21</code>) but the compiler is trimming the values?</li> </ul>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload