I was writing a piece of code that prevents an ushort from overflow/underflow'ing. Before that I try:
ushort a = 0; //ushort.MinValue
a -= 1; //returns 65535 (ushort.MaxValue)
Then I write the real code, and I expect this to "fail" (not able to detect underflow):
ushort oldValue, rate, delta;
ushort newValue = Math.Max(ushort.MinValue, oldValue - rate * delta);
Interestingly an error (CS0266) prevents me from building it. While I expect that C# will use the ushort Max(ushort, ushort)
overload, it is using int Max(int, int)
overload and that ushort
values are converted into int
automatically. Of course when I explicit cast the result to ushort
this works fine.
This makes me think, is C# detecting that a possible underflow can occur, so it's using int
to do the comparison for me?
This is because
oldValue - rate * delta
's result is of typeint
. This is because the "minimum data type" for which operators +, -, * and / are defined isint
. Sobyte
,ushort
, etc. are converted toint
first. Then, the result is again anint
. So you need to cast explicitly toushort
.Or you could use
Convert.ToUInt16
which will raise an exception if an overflow occurs.