Today I was trying to implement reading of
ushort values from a little-endian byte array. The code to retrieve a single value was pretty simple – shift the second byte by 8 to the left and add the first byte:
|var result = (ushort)(data[position + 1] << 8 + data[position]);|
What could possibly go wrong?
It turned out quite a bit. The code was giving me completely wrong results. So I used
BitConverter.ToUInt16 and indeed the values returned were entirely different than mine. I checked the binary notation via calculator and then it hit me. The innocent looking
<< operator has lower precedence than
+ (as confirmed by the documentation). This means my code first performed:
|8 + data[position]|
And then shifted
data[position + 1] by the resulting number to the left. When I instead rewrote the code as:
|var result = (ushort)((data[position + 1] << 8) + data[position]); //note the additional parentheses|
Everything was working great again.
The moral of this story is – whenever in doubt, add two keystrokes worth of parentheses. The code will be more understandable to you, other developers and especially to the computer.
PS: I ended up editing the code once more and replaced
+ by logical OR, which not only shows the intention better but also leaving out the parentheses will, in this case, not have such fatal consequences.
|var result = (ushort)((data[position + 1] << 8) | data[position]);|