3
static void Main(string[] args)
{
  int n;
  byte b;
  n = 256;
  b = (byte) n;
  Console.WriteLine(b); //0
}

C# byte range is 0 to 255 and hence I try to cast an int of 256 to byte and see what will happen.

Surprisingly it returns 0 instead of 255 or better yet give me an overflow exception?

UPDATES: I'm trying it on macos which is Mono, if it matters and .NET Framework 4.7

2

2 Answers 2

6

That is the expected behaviour. If you think about it, 256 is one "1" followed by 8 zeroes in binary. When you take away everything except the least significant 8 bits, you get 8 zeroes, which is the value 0.

From the C# language specification §6.2.1:

For a conversion from an integral type to another integral type, the processing depends on the overflow checking context (§7.6.12) in which the conversion takes place:

  • In a checked context, the conversion succeeds if the value of the source operand is within the range of the destination type, but throws a System.OverflowException if the value of the source operand is outside the range of the destination type.
  • In an unchecked context, the conversion always succeeds, and proceeds as follows.
    • If the source type is larger than the destination type, then the source value is truncated by discarding its “extra” most significant bits. The result is then treated as a value of the destination type.

If you want an exception, you can used checked:

b = checked((byte) n);
Sign up to request clarification or add additional context in comments.

5 Comments

Great! But is that also means that in order to have a absolute predictable outcome when dealing with numbers, it's recommended to have checked on every arithmetic operations? Or type casting?
If you always want exception when overflow occurs, then you should put checked whenever there is possibility of overflow. But sometimes "wrapping around" might be preferred though. @Isaac
Out of curiosity, since this involves in another additional checking, will it affect the performance in anyway? Or its neglectable?
@Isaac It does add an additional check, but really, you should only deal with performance problems when you actually have them, and that you are sure that it's caused by checked statements, not some other code, which is unlikely.
If you want it to always throw an exception, you can add the -checked compiler option, in .csproj file it would be <CheckForOverflowUnderflow>true</CheckForOverflowUnderflow>
2

I would like to complement the previous answer.

Take a look at this:

255 -> 11111111 +

001 -> 00000001

256 -> 100000000

As you can see. We have 256 in binary format, but as your number is eight bits, 1 can't be stored. This leave the number 00000000 which is zero.

This is more theory than C# specific question. But i think this is important to understand.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.