默认情况下,C# 在处理数字时不检查溢出。这包括诸如从int.MaxValue加到int.MinValue乘法的换行,以及当你将longs 转换为ints 时。要控制这一点,请使用checkedandunchecked关键字或/checked编译器选项。
该值1942903641是您long被截断为int. 它来自long值的 32 个最低有效位,作为二进制补码有符号整数。
使用 时foreach,重要的是要知道,如果您声明的类型与可枚举的类型不匹配,它会将其视为您已转换为该类型。foreach (int i in myCollection)编译成类似的东西int i = (int)myEnumerator.Current;,不是int i = myEnumerator.Current;。您可以使用它foreach (var i in myCollection)来避免将来出现此类错误。var 建议在forandforeach语句中使用 for 循环变量。
您可以在以下示例中看到各种事情的结果(十六进制输出用于更清楚地显示截断:它们具有相同的结束数字,int只是缺少一些更有效的数字):
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"));
}
这输出:
B3A73CE5B59
73CE5B59
It threw! Arithmetic operation resulted in an overflow.
B3A73CE5B59
73CE5B59
73CE5B59