Q:

C#: The result of casting a negative integer to a byte

I was a looking at the source code of a project, and I noticed the following statement (both keyByte and codedByte are of type byte):
return (byte)(keyByte - codedByte);

I'm trying now to understand what would the result be in cases where keyByte is smaller than codedByte, which results in a negative integer.
After some experiments to understand the result of casting a negative integer which has a value in the range [-255 : -1], I got the following results:
byte result = (byte) (-6);  // result = 250
byte result = (byte) (-50); // result = 206
byte result = (byte) (-17); // result = 239
byte result = (byte) (-20); // result = 236

So, provided that -256 < a < 0 , I was able to determine the result by:
result = 256 + a;

My question is: should I always expect this to be the case?

A:

Yes.  Remember, there's no such thing as "-" in the domain of a .Net "Byte":

http://msdn.microsoft.com/en-us/library/e2ayt412.aspx
Because Byte is an unsigned type, it cannot represent a negative
  number. If you use the unary minus (-) operator on an expression that
  evaluates to type Byte, Visual Basic converts the expression to Short
  first. (Note: substitute any CLR/.Net language for "Visual Basic")

ADDENDUM:
Here's a sample app:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace TestByte
{
    class Program
    {
        static void Main(string[] args)
        {
            for (int i = -255; i < 256; i++)
            {
                byte b = (byte)i;
                System.Console.WriteLine("i={0}, b={1}", i, b);
            }
        }
    }
}

And here's the resulting output:
testbyte|more
i=-255, b=1
i=-254, b=2
i=-253, b=3
i=-252, b=4
i=-251, b=5
...
i=-2, b=254
i=-1, b=255
i=0, b=0
i=1, b=1
...
i=254, b=254
i=255, b=255

A:

Yes, that will always be the case (i.e. it is not simply dependent on your environment or compiler, but is defined as part of the C# language spec).  See http://msdn.microsoft.com/en-us/library/aa691349(v=vs.71).aspx:

In an unchecked context, the result is truncated by discarding any high-order bits that do not fit in the destination type.

The next question is, if you take away the high-order bits of a negative int between -256 and -1, and read it as a byte, what do you get?  This is what you've already discovered through experimentation: it is 256 + x.
Note that endianness does not matter because we're discarding the high-order (or most significant) bits, not the "first" 24 bits.  So regardless of which end we took it from, we're left with the least significant byte that made up that int.

A:

Here is an algorithm that performs the same logic as casting to byte, to help you understand it:
For positives:
byte bNum = iNum % 256;

For negatives:
byte bNum = 256 + (iNum % 256);

It's like searching for any k which causes x + 255k to be in the range 0 ... 255. There could only be one k which produces a result with that range, and the result will be the result of casting to byte.
Another way of looking at it is as if it "cycles around the byte value range":
Lets use the iNum = -712 again, and define a bNum = 0.
We shall do iNum++; bNum--; untill iNum == 0:
iNum = -712;
bNum = 0;

iNum++; // -711
bNum--; // 255 (cycles to the maximum value)

iNum++; // -710
bNum--; // 254

... // And so on, as if the iNum value is being *consumed* within the byte value range cycle.

This is, of course, just an illustration to see how logically it works.

