如何阻止整数除法抛出 OverflowException?

发布于 2024-08-01 21:12:24 字数 678 浏览 6 评论 0原文

当我不想要它们时,我会收到 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。

如果我对此有任何了解,这可能就是晦涩方法的文档的重要性。

I am getting OverflowException's thrown at me when I don't want them (or so I think). I am performing some odd calculations where I expect the values to overflow, discarding overflowed bits. It seems I can't get this to work properly though. Basically this is one pair of i and j which happens as I iterate over huge sets (int.MinValue to 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);

Update:

The expected mathematic value of -2147483648 / -1 is 2147483648. However, this certain code doesn't really attempt to find the number. This is part of a series of bit manipulation things gone a bit hard to understand. To be honest, I don't even know myself what the intention was because I didn't really document the method, and all it took was one day away from it to raise serious WTF-bubbles over my head. All I know it works as intended with special code designed to handle the case.

About the expected value:

Since int can only hold 2147483647 at it's max, I expect to discard the overflow yielding value 0.

If I've learned anything about this at all, it's probably the importance of documentation for obscure methods.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

只有影子陪我不离不弃 2024-08-08 21:12:24

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

因此,如果您想避免 OverflowException,您只需需要处理这种情况。 你想让它做什么? 编写一个方法来准确识别这种情况,否则进行正常除法。

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

I believe this is the only case in which you'll get this exception. It's the only division within the Int32 range which can overflow. (There's division by zero of course, but that's a different exception.)

So if you want to avoid OverflowException you only need to deal with this case. What do you want it to do? Write a method which spots this exact case, and otherwise does normal division.

Note: this is also why you shouldn't try to reverse a comparison by just negating the result. If you want to sort something in descending order instead of ascending, then instead of using -Compare(x, y) use Compare(y, x). The negation doesn't give overflow for int.MinValue (unless you're in a checked context) - it just silently returns int.MinValue.

子栖 2024-08-08 21:12:24

二进制补码意味着整数范围从 2^32 - 1 到 -2^32,因此 -2147483648 / -1 返回一个无法用 int 表示的数字。

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

Twos complement means that integers will range from 2^32 - 1 to -2^32, so -2147483648 / -1 is returning a number which can't be represented by an int.

You could try putting it into a long. There's no reason to use a var in this situation.

抹茶夏天i‖ 2024-08-08 21:12:24

您可以通过在 Int64 之间进行一些转换来解决此问题:

var x = (int)((long)i / j);

You can workaround this with a bit of casting to/from Int64:

var x = (int)((long)i / j);
倾听心声的旋律 2024-08-08 21:12:24

你做这个。 为什么要在这里使用 var ? 它失去了向您显示算术结果类型的能力,全部用于保存 1 个字符...

long x = (long)i / j;

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

int x = (int)Math.Min((long)i / j, int.MaxValue);

You do this. Why would you use var here? It loses the ability to show you the type of arithmetic result all for saving 1 character...

long x = (long)i / j;

If you want saturation, you can:

int x = (int)Math.Min((long)i / j, int.MaxValue);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文