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 longs to ints. 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