Can anyone explain why the following doesn't compile?
byte b = 255 << 1
The error:
Constant value '510' cannot be converted to a 'byte'
I'm expecting the following in binary:
1111 1110
The type conversion has stumped me.
Can anyone explain why the following doesn't compile?
byte b = 255 << 1
The error:
Constant value '510' cannot be converted to a 'byte'
I'm expecting the following in binary:
1111 1110
The type conversion has stumped me.
have you tried casting it?
byte b = (byte)(255 << 1)
This is an interesting approach - the above code will work if wrapped in a unchecked
block like this:
unchecked
{
byte b = (byte)(255 << 1);
}
Since it is unchecked
the value is truncated to the intended value of 254. So it is possible to do this with a cast!
You are shifting 255 by 1 bit, then trying to assign it to a byte.
255 << 1 is 510
, and 510 won't fit in to a byte.
Numeric literals in C# are int
, not byte
(and the bit shift will be evaluated by the compiler, hence only the 510 remains). You are therefore trying to assign a value to a byte
which does not fit. You can mask with 255:
byte b = (255 << 1) & 0xFF
to reduce the result to 8 bits again. Unlike Java, C# does not allow overflows to go by undetected. Basically you'd have two sensible options when trying to assign 510 to a byte: Either clamp at the maximum value, then you'd get 255, or throw away the bits that do not fit, in which case you'd get 254.
You can also use unchecked
, as lassevk mentioned:
byte b = unchecked((byte)(255 << 1));
The result of the <<
operator is an Int32
, not what you put into it.
You need to cast the result of the shift, not the input. Additionally, it will produce an overflow (it is larger than a byte afterall), so you need to specify that you need an unchecked cast.
In other words, this will work:
Byte b = unchecked((Byte)(255 < 1));
And since << has a higher precedence than & you can save the brackets:
byte b = 255 << 1 & 0xff;