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

时间:2010-01-13 12:09:55

标签: c# overflow

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

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

事实证明,结果太大而不适合int,但这不会导致溢出错误或其他什么?相反,它只返回了一个远离真实答案的值。

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

6 个答案:

答案 0 :(得分:85)

默认情况下,C#整数操作在溢出时不会抛出异常。您可以通过项目设置或计算checked

来实现
int result = checked(largeInt + otherLargeInt);

现在操作将抛出。

相反的是unchecked,这使得任何操作都明确取消选中。显然,只有在项目设置中启用了检查操作时,这才有意义。

答案 1 :(得分:19)

在C#中,不抛出OverflowException(在VB中,默认情况下抛出异常)。

要获得重复,您必须将代码嵌入checked上下文中:

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更详细地解释:

  

算术,铸造或   转换操作抛出一个   OverflowException,操作必须   发生在检查的上下文中。通过   默认,算术运算和   检查Visual Basic中的溢出;   在C#中,它们不是。如果操作   发生在未经检查的上下文中   通过丢弃任何结果来截断结果   不适合的高阶位   目的地类型。

答案 2 :(得分:14)

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

  

选项1

您必须通过转到启用异常 项目=> properties =>构建标签=>高级=>检查算术溢出下溢。(确保勾选选项)

enter image description here

确保勾选选项

  

选项2

使用选中的块并抛出溢出异常来处理这种情况。示例代码段将是

        try
        {
            checked
            {
                int y = 1000000000;
                short x = (short)y;
            }
        }
        catch (OverflowException ex)
        {
            MessageBox.Show("Overflow");
        }
        catch (Exception ex)
        {
            MessageBox.Show("Error");
        }

希望这会对你有所帮助...... :)

答案 3 :(得分:7)

我已经添加了一个cmt,但对于你们中的一些人来说这可能很有趣:

msdn告诉我们:

  

整数算术溢出   抛出OverflowException或   抛弃最重要的部分   结果

  

始终为十进制算术溢出   抛出OverflowException。

  

当整数溢出时,什么   发生取决于执行   上下文,可以检查或   选中。在检查的上下文中,   抛出OverflowException。在一个   未经检查的背景,最多   结果的重要部分是   丢弃并继续执行。   因此,C#为您提供了选择   处理或忽略溢出。

答案 4 :(得分:6)

默认情况下,C#不检查整数上的算术溢出。您可以使用/checked compiler option或在Visual Studio中启用“检查算术溢出/下溢”(项目属性 - 构建 - 高级)来更改此项。

您可以根据具体情况使用checked and unchecked keywords覆盖默认值。如果您依赖于在一段代码中进行检查,则使用checked明确启用它将是一个好主意。

int j = checked(i * 2);

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

请注意,浮点运算从不抛出OverflowException,十进制运算总是抛出OverflowException。另请参阅C# operators

答案 5 :(得分:0)

我有一个数学运算被截断而不会产生错误,即使目标是一个大变量:

Int count1 = (1000*10000) x 1024; //an exception is not raised

即使目标变量很大,它仍然会被截断并且不会抛出任何异常,我不明白为什么 count2 被视为 int32 而不是 int64

Int64 count2 = (1000*10000) x 1024;

注意:10000 是从配置文件中读取的变量