在C#中处理整数溢出的最佳方法是什么?

Ben*_*key 42 .net c# integer overflow

处理整数溢出是一项常见任务,但在C#中处理它的最佳方法是什么?是否有一些语法糖比其他语言更简单?或者这真的是最好的方式吗?

int x = foo();
int test = x * common;
if(test / common != x)
    Console.WriteLine("oh noes!");
else
    Console.WriteLine("safe!");
Run Code Online (Sandbox Code Playgroud)

Mic*_*ito 102

我不需要经常使用它,但您可以使用checked关键字:

int x = foo();
int test = checked(x * common);
Run Code Online (Sandbox Code Playgroud)

如果溢出,将导致运行时异常.来自MSDN:

在已检查的上下文中,如果表达式生成的值超出目标类型的范围,则结果取决于表达式是常量还是非常量.常量表达式导致编译时错误,而非常量表达式在运行时计算并引发异常.

我还应该指出,还有另一个C#关键字,unchecked当然与其相反checked并忽略溢出.您可能想知道何时使用unchecked它,因为它似乎是默认行为.好吧,有一个C#编译器选项,它定义了如何处理checkedunchecked处理表达式:/ checked.您可以在项目的高级构建设置下进行设置.

如果你有很多需要检查的表达式,最简单的方法就是设置/checked构建选项.然后,除非被包装,否则任何溢出的表达式unchecked都将导致运行时异常.

  • 为什么未选中默认行为?使用已检查是否有任何性能问题? (3认同)
  • @KFL“由于检查溢出需要时间,因此在没有溢出危险的情况下使用未经检查的代码可能会提高性能。但是,如果有可能发生溢出,则应使用经过检查的环境。” 请参阅http://msdn.microsoft.com/en-us/library/a569z7k8.aspx。我还相信默认值是未选中的,因为它与 C / C++ 行为类似。 (3认同)

Jar*_*Par 19

请尝试以下方法

int x = foo();
try {
  int test = checked (x * common);
  Console.WriteLine("safe!");
} catch (OverflowException) {
  Console.WriteLine("oh noes!");
}
Run Code Online (Sandbox Code Playgroud)


Chi*_*joo 7

最好的方法是Micheal Said - 使用Checked关键字.这可以这样做:

int x = int.MaxValue;
try   
{
    checked
    {
        int test = x * 2;
        Console.WriteLine("No Overflow!");
    }
}
catch (OverflowException ex)
{
   Console.WriteLine("Overflow Exception caught as: " + ex.ToString());
}
Run Code Online (Sandbox Code Playgroud)


Alo*_*kin 6

有时,最简单的方法就是最好的方法。我想不出更好的方法来写你所写的内容,但你可以将其简短为:

int x = foo();

if ((x * common) / common != x)
    Console.WriteLine("oh noes!");
else
    Console.WriteLine("safe!");
Run Code Online (Sandbox Code Playgroud)

请注意,我没有删除该变量,因为调用三次x是愚蠢的。foo()

  • 有用,除非您计划使用结果(x*common),否则您的缩短将需要计算两次...... (3认同)

小智 5

旧线程,但我刚刚遇到了这个。我不想使用异常。我最终得到的是:

long a = (long)b * (long)c;
if(a>int.MaxValue || a<int.MinValue)
    do whatever you want with the overflow
return((int)a);
Run Code Online (Sandbox Code Playgroud)

  • 您错过了他/她在检查 int 边界之前很久就转换为的事实。所以它会工作,只要它不溢出长。 (5认同)