2010-05-29 62 views
33

这是怎么回事?我做一个简单的乘法:不应该导致溢出?它不!

Int64 x = 11111111111; 
Int64 y = 11111111111; 
Int64 z = x * y; 

,并在乘法结束,Z显示的值:

-5670418394979206991

这显然已经溢出,但不会引发异常。我想要一个被提出,但...

请注意,这是在Windows Phone 7上,但我不认为这对此问题有任何影响。还是呢?

回答

43

您可以使用一个检查块作为已指出其他答案:

checked 
{ 
    long x = 11111111111; 
    long y = 11111111111; 
    long z = checked(x * y); 
    // ... 
} 

导致异常:

发生OverflowException:算术运算导致溢出。

如果你只是在做你需要检查你可以使用checked expression,而不是一个单一的操作:

long x = 11111111111; 
long y = 11111111111; 
long z = checked(x * y); 

您还可以设置/checked compiler option有默认的检查。

设置在Visual Studio开发环境中,该编译器选项:

  1. 打开项目的属性页对话框。有关详情,请参阅Setting Visual C# Project Properties
  2. 单击配置属性文件夹。
  3. 点击Build属性页。
  4. 修改检查算术溢出/下溢属性

如果更改默认选中,您可以使用选中块或表达式来再次获得未经检查的行为。

+25

请注意,未选中的原因是默认的原因是(1)99%的时间整数运算不在边界附近,(2)检查的算术运行速度较慢。这是C#设计出于性能原因选择违约危险的罕见情况之一。 – 2010-05-29 15:36:51

+0

x86抖动使用简单的jno,分支预测总是很好,不能超过单个周期。 – 2010-06-13 11:46:47

+0

并不是说它必然与C#的设计有关,但在这个特定情况下,我们正在讨论ARM。 x86抖动的行为有些学术性 – Stewart 2010-06-18 18:19:59

26

Check it

checked 
{ 
    Int64 x = 11111111111; 
    Int64 y = 11111111111; 
    Int64 z = x * y; 
} 
+6

宾果!每天学点新东西,我知道!谢谢。并且非常感谢SO。 – Cyberherbalist 2010-05-29 09:19:04

8

尝试:

checked 
{ 
    Int64 x = 11111111111; 
    Int64 y = 11111111111; 
    Int64 z = x * y; 
} 
8

编译器假设你想这样做的,并与溢出继续进行。如果需要将溢出视为操作异常,请围绕checked执行操作,并在运行时引发异常。

checked 
{ 
    Int64 x = 11111111111; 
    Int64 y = 11111111111; 
    Int64 z = x * y; 
} 

System.OverflowException:一个异常类型System.OverflowException的 是 抛出。