C # 中 int 没有溢出异常?

我有这个怪异的经验与问题10在 欧拉计划(伟大的网站的方式)。作业是计算所有低于200万的素数之和。

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

结果表明,结果太大,无法放入 int 类型,但这不会导致溢出错误或其他问题吗?相反,它只是返回了一个远离真实答案的值。

当我把字体改成长的时候,一切都好极了。

51874 次浏览

C# integer operations don’t throw exceptions upon overflow by default. You can achieve that via the project settings, or by making the calculation checked:

int result = checked(largeInt + otherLargeInt);

Now the operation will throw.

The opposite is unchecked, which makes any operation explicitly unchecked. Obviously, this only makes sense when you’ve got checked operations enabled in the project settings.

In C# an OverflowException is not thrown (in VB the exception is thrown per default).

To get the excpetion you have to embed your code in a checked context:

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 explains in more detail:

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.

I have already added a comment, but maybe it would be interesting for some of you:

msdn tells us:

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

but

Decimal arithmetic overflow always throws an OverflowException.

also

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.

By default, C# does not check for arithmetic overflow on integers. You can change this with the /checked compiler option or by enabling "Check for arithmetic overflow/underflow" in Visual Studio (project properties - Build - Advanced).

您可以根据具体情况使用ABC0 and unchecked keywords来覆盖默认值。如果您依赖于在一段代码中发生的检查,那么使用checked显式地启用它将是一个好主意。

int j = checked(i * 2);


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

Note that floating point operations never throw an OverflowException, and decimal operations always throw an OverflowException. See also C# operators.

It's because, by default C# do not throw any exception for integer overflow as well as underflow. There are couple of things you can do here.

Option 1

You have to enable the exception to be thrown by go to Project => properties => Build tab => Advanced => check for arithmetic overflow underflow.(make sure you tick the option)

enter image description here

Make sure you tick the option

Option 2

Use a checked block and throw an overflow exception to handle the situation. A sample code snippet would be

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

I have a mathematical operation that is truncated without generating error, even if the destination is a large variable:

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

OR

Even if the target variable is large it is still truncated and throws no exception and I don't understand why count2 is treated as an int32 and not an int64

Int64 count2 = (1000*10000) x 1024;

Note: 10000 is a variable read from a configuration file