The shifting operators are used to do an arithmetic shift to the bits of an integral numeric value, either to the left or the right.
var number = 14; // ...01110 (14) var left = number << 1; // ...11100 (28) var right = number >> 1; // ...00111 (7)
Therefore, shifting an integral number by 0 is equivalent to doing nothing, since the bits do not move any positions to the left or the right.
On the other hand, shifting an integral number by a value greater than their count of bits minus one (n_bits-1) is equivalent to
shifting by the value modulo the bit count of the number (value % n_bits).
In the case of int and uint, which take 32 bits in the memory, the shift count is given by the five low-order bits of the
second operand, which can represent numbers from 0 to 31. This means that numbers having the same five low-order bits are treated the same by the
shift operators.
var one = 0b0_00001; var thirtyThree = 0b1_00001; // Same five low-order bits, 33 % 32 = 1 var shifted1 = 42 << one; // Results in 84 var shifted2 = 42 << thirtyThree; // Results in 84
Note that integral number with a less than 32-bit quantity (e.g. short, ushort) are implicitly converted to
int before the shifting operation and so the rule for int/uint applies.
If the first operand is a long or ulong (64-bit quantity), the shift count is given by the six low-order bits of the
second operand. That is, the actual shift count is 0 to 63 bits.
This rule doesn’t raise an issue when the shift by zero is obviously for cosmetic reasons:
bytes[loc+0] = (byte)(value >> 8); bytes[loc+1] = (byte)(value >> 0);
short s = 1; short shortShift1 = (short)(s << 0); // Noncompliant: the value does not change short shortShift2 = (short)(s << 33); // Noncompliant: this is equivalent to shifting by 1 int i = 1; int intShift = i << 33; // Noncompliant: this is equivalent to shifting by 1 long lg = 1; long longShift1 = lg << 0; // Noncompliant: the value does not change long longShift2 = lg << 65; // Noncompliant: this is equivalent to shifting by 1
short s = 1; short shortShift1 = s; short shortShift2 = (short)(s << 1); int i = 1; var intShift = i << 1; long lg = 1; var longShift1 = lg; var longShift2 = lg << 1;