By default, C# does not check for overflows when processing numbers. This includes things like wrapping from int.MaxValue
to int.MinValue
in addition and multiplication, and when you cast long
s to int
s. To control this, use the checked
and unchecked
keywords, or the /checked
compiler option.
The value 1942903641
is the result when your long
is truncated to an int
. It comes from the 32 least significant bits of the long
value, taken as a two's complement signed integer.
When using foreach
, it's important to know that if you declare a type that doesn't match the type of the enumerable, it will treat it as if you casted to that type. foreach (int i in myCollection)
compiles to something like int i = (int)myEnumerator.Current;
, not int i = myEnumerator.Current;
. You could use foreach (var i in myCollection)
to avoid such mistakes in the future. var
is recommended to use for the loop variable in for
and foreach
statements.
You can see the results of various things in the following example (hexadecimal output is used to show the truncation more clearly: they have the same ending digits, the int
just lacks some of the more significant digits):
checked
{
Int64 a = 12345678912345;
Console.WriteLine(a.ToString("X"));
Console.WriteLine((a % ((long)uint.MaxValue + 1L)).ToString("X"));
try
{
Console.WriteLine(((int)a).ToString("X")); // throws exception
}
catch (Exception e)
{
Console.WriteLine("It threw! " + e.Message);
}
}
unchecked
{
Int64 a = 12345678912345;
Console.WriteLine(a.ToString("X"));
Console.WriteLine((a % (long)Math.Pow(2, 32)).ToString("X"));
Console.WriteLine(((int)a).ToString("X"));
}
This outputs:
B3A73CE5B59
73CE5B59
It threw! Arithmetic operation resulted in an overflow.
B3A73CE5B59
73CE5B59
73CE5B59