为什么这个特定操作在C#中溢出(参见CS0220)?

时间:2009-04-03 09:47:41

标签: c# compiler-construction overflow

我尝试用字节存储的半字节信息构建一个大的Int64。

以下代码行按预期工作:

Console.WriteLine("{0:X12}", (Int64)(0x0d * 0x100000000));
Console.WriteLine("{0:X12}", (Int64)(0x0d * 0x1000000));
Console.WriteLine("{0:X12}", (Int64)(0x0d * 0x100000));

为什么以下行导致编译错误CS0220“操作在编译时以检查模式溢出”而其他操作没有?

Console.WriteLine("{0:X12}", (Int64)(0x0d * 0x10000000));

结果将是:

FFFFFFFFD0000000

而不是:

0000D0000000

任何人都能解释一下吗?我现在将转换为移位运算符,但仍然很好奇为什么这种方法不起作用!

更新:使用(Int64)(0x0d <&lt; 28)时也会发生错误。

3 个答案:

答案 0 :(得分:2)

您需要将常量值标记为long(Int64s)或可能ulongs(UInt64s),否则默认情况下它们将解释为int(即Int32s),显然会导致溢出。在这种情况下,在乘法运算后进行铸造对你没有任何好处。

尚未测试,但此代码应该有效:

Console.WriteLine("{0:X12}", 0x0dL * 0x100000000L);
Console.WriteLine("{0:X12}", 0x0dL * 0x1000000L);
Console.WriteLine("{0:X12}", 0x0dL * 0x100000L);

答案 1 :(得分:1)

整数文字的类型为Int32(即使是十六进制)。使用“L”后缀使它们变长(Int64)。

Console.WriteLine("{0:X12}", 0x0dL * 0x100000000L);

答案 2 :(得分:-1)

乍一看我猜它正在用Int32进行乘法,并且溢出。您需要将各个操作数强制转换为Int64,然后将它们相乘。现在你只是在投射结果。

那就是说,我不知道为什么它只能找到那一行的问题,而不是第一行的问题。

ND