2

当我不想要它们时(或者我认为),我正在向我抛出OverflowException 。我正在执行一些奇怪的计算,我希望这些值会溢出,丢弃溢出的位。看来我无法让它正常工作。基本上这是一对 i 和 j,当我迭代巨大的集合(int.MinValue 到 int.MaxValue)时会发生这种情况。

// i and j are ints
// i is -2147483648
// j is -1
var x = i / j;

// I also tried using unchecked keyword, but it doesn't help    
var x = unchecked(i / j);

更新:

-2147483648 / -1 的预期数学值是 2147483648。但是,这个特定的代码并没有真正尝试找到数字。这是一系列难以理解的位操作的一部分。老实说,我什至不知道自己的意图是什么,因为我并没有真正记录该方法,并且只需要一天时间就可以在我的头上引发严重的 WTF 泡沫。据我所知,它使用旨在处理此案的特殊代码按预期工作。

关于期望值:

由于 int 只能保持 2147483647 的最大值,我希望丢弃产生值 0 的溢出。

如果我对此有所了解,那可能是文​​档对于晦涩的方法的重要性。

4

4 回答 4

6

我相信这是唯一会遇到此异常的情况。它是该Int32范围内唯一可以溢出的分区。(当然有除以零,但这是一个不同的例外。)

所以如果你想避免OverflowException,你需要处理这种情况。你想让它做什么?编写一个方法来发现这种确切的情况,否则进行正常除法。

注意:这也是为什么你不应该试图通过否定结果来反转比较。如果您想按降序而不是升序对某些内容进行排序,则不要使用-Compare(x, y)use Compare(y, x)。否定不会溢出 for int.MinValue(除非您处于已检查的上下文中)-它只是默默地返回int.MinValue.

于 2009-08-19T15:49:26.407 回答
3

二进制补码意味着整数的范围从 2^32 - 1 到 -2^32,因此 -2147483648 / -1 返回一个不能用int.

您可以尝试将其放入long. 在这种情况下没有理由使用 a var

于 2009-08-19T15:39:02.903 回答
0

您可以通过一些转换来解决这个问题Int64

var x = (int)((long)i / j);
于 2009-08-19T15:54:02.733 回答
0

你来做这件事。为什么要var在这里使用?它失去了向您显示算术结果类型的能力,所有这些都是为了保存 1 个字符......

long x = (long)i / j;

如果你想要饱和,你可以:

int x = (int)Math.Min((long)i / j, int.MaxValue);
于 2009-08-19T16:40:35.883 回答