19

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.

Helen
  • 87,344
  • 17
  • 243
  • 314
Chris S
  • 64,770
  • 52
  • 221
  • 239

7 Answers7

37

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));
Community
  • 1
  • 1
Joey
  • 344,408
  • 85
  • 689
  • 683
  • Not sure why I thought 255 would be stored as a 8 bit – Chris S Apr 10 '09 at 14:41
  • Well, 255 fits, everything above doesn't :) – Joey Apr 10 '09 at 14:42
  • 4
    It should be noted, as I was pushed here from another thread, that even if you have two bytes, any bitwise operation on them will return an int. – Ben Lesh Aug 01 '09 at 03:52
  • Silly question, why do you use a hex representation of 255 instead of just using 255? – Razor Jul 07 '10 at 06:19
  • 1
    @Sir: Habit when using numbers as bitmasks. If you're `and` -ing or `or` -ing with a number you don't care about its decimal representation; you want to see immediately what bits are set and which are not. – Joey Jul 07 '10 at 09:37
8

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.

Steve
  • 8,469
  • 1
  • 26
  • 37
6

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));
Michel de Ruiter
  • 7,131
  • 5
  • 49
  • 74
Lasse V. Karlsen
  • 380,855
  • 102
  • 628
  • 825
5
byte b = 0xff & (255 << 1);
Michael Burr
  • 333,147
  • 50
  • 533
  • 760
3

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!

Andrew Hare
  • 344,730
  • 71
  • 640
  • 635
Daniel A. White
  • 187,200
  • 47
  • 362
  • 445
1
255 << 1

will give you more than one byte.

Otávio Décio
  • 73,752
  • 17
  • 161
  • 228
0

And since << has a higher precedence than & you can save the brackets:

byte b = 255 << 1 & 0xff;
sipsorcery
  • 30,273
  • 24
  • 104
  • 155