代码之家  ›  专栏  ›  技术社区  ›  Statement

如何停止整数除法上引发的溢出异常?

  •  2
  • Statement  · 技术社区  · 15 年前

    我得到 溢出异常 当我不想要他们的时候(或者我认为是这样),他们就会向我扔东西。我正在执行一些奇怪的计算,我期望值溢出,丢弃溢出的位。不过,我似乎不能让它正常工作。基本上,这是一对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 回复  |  直到 15 年前
        1
  •  6
  •   Jon Skeet    15 年前

    我相信这是 只有 在这种情况下你会得到这个例外。它是 Int32 可能溢出的范围。(当然有除以零的方法,但这是另一个例外。)

    所以如果你想避免 OverflowException 只有 需要处理这个案子。你想要它做什么?写一个方法找出这个 准确的 否则做正常除法。

    注意:这也是为什么你不应该仅仅通过否定结果来逆转比较。如果要按降序而不是升序排序,则不要使用 -Compare(x, y) 使用 Compare(y, x) . 否定 溢出 int.MinValue (除非您处于选中的上下文中)-它只是静默返回 极小值 .

        2
  •  3
  •   Pike65    15 年前

    两个补码意味着整数的范围是2^32-1到-2^32,所以-2147483648/-1返回的数字不能用 int .

    你可以试着把它放进 long . 没有理由使用 var 在这种情况下。

        3
  •  0
  •   LukeH    15 年前

    你可以通过一点投射来解决这个问题。 Int64 :

    var x = (int)((long)i / j);
    
        4
  •  0
  •   Sam Harwell    15 年前

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

    long x = (long)i / j;
    

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

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