C#中的int是否没有溢出异常?

No overflow exception for int in C#?

我在Euler项目(顺便说一句,很棒的网站)上遇到了第10个问题的怪异经历。 任务是计算低于200万的所有素数之和。

我使用一个整数作为总和,我的算法产生了一个答案,但是当我粘贴它以验证答案时,这是错误的。

原来,结果太大而无法放入int中,但这是否会导致溢出错误或其他原因? 相反,它只是返回了一个与实际答案相差很远的值。

当我将类型更改为long时,一切都是笨拙的。


默认情况下,C#整数运算不会在溢出时引发异常。您可以通过项目设置或通过计算checked来实现:

1
int result = checked(largeInt + otherLargeInt);

现在该操作将抛出。

相反的是unchecked,它使任何操作都显式地未选中。显然,只有在项目设置中启用了选中的操作后,这才有意义。


在C#中,不会引发OverflowException(在VB中,默认情况下会引发异常)。

要获得排他性,您必须将代码嵌入到checked上下文中:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
byte value = 241;
checked
{
    try
    {
        sbyte newValue = (sbyte) value;
        Console.WriteLine("Converted the {0} value {1} to the {2} value {3}.",
            value.GetType().Name, value,
            newValue.GetType().Name, newValue);
    }
    catch (OverflowException)
    {
        Console.WriteLine("Exception: {0} > {1}.", value, SByte.MaxValue);
    }
}

MSDN更详细地解释:

For the arithmetic, casting, or
conversion operation to throw an
OverflowException, the operation must
occur in a checked context. By
default, arithmetic operations and
overflows in Visual Basic are checked;
in C#, they are not. If the operation
occurs in an unchecked context, the
result is truncated by discarding any
high-order bits that do not fit into
the destination type.


这是因为,默认情况下,C#不会对整数溢出和下溢引发任何异常。您可以在这里做几件事。

Option 1

您必须启用转到引发的异常
项目=>属性=>生成选项卡=>高级=>检查算术溢出下溢。(确保选中该选项)

enter image description here

确保您勾选该选项

Option 2

使用检查的块并引发溢出异常来处理这种情况。一个示例代码片段将是

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
        try
        {
            checked
            {
                int y = 1000000000;
                short x = (short)y;
            }
        }
        catch (OverflowException ex)
        {
            MessageBox.Show("Overflow");
        }
        catch (Exception ex)
        {
            MessageBox.Show("Error");
        }

希望这个能对您有所帮助... :)


我已经添加了cmt,但是对于某些人来说可能很有趣:

msdn告诉我们:

Integer arithmetic overflow either
throws an OverflowException or
discards the most significant bits of
the result

Decimal arithmetic overflow always
throws an OverflowException.

When integer overflow occurs, what
happens depends on the execution
context, which can be checked or
unchecked. In a checked context, an
OverflowException is thrown. In an
unchecked context, the most
significant bits of the result are
discarded and execution continues.
Thus, C# gives you the choice of
handling or ignoring overflow.


默认情况下,C#不检查整数的算术溢出。您可以使用/checked编译器选项或通过在Visual Studio中启用"检查算术上溢/下溢"(项目属性-生成-高级)来更改此设置。

您可以使用checkedunchecked关键字逐个覆盖默认值。如果您依靠在一段代码中进行检查,则最好使用checked启用它。

1
2
3
4
5
6
7
int j = checked(i * 2);

checked
{
    int j = i * 2;
    // Do more stuff
}

请注意,浮点运算永远不会抛出OverflowException,而十进制运算总是会抛出OverflowException。另请参见C#运算符。