【问题标题】:What is an integer overflow error?什么是整数溢出错误?
【发布时间】:2010-04-14 21:46:16
【问题描述】:

什么是整数溢出错误? 为什么我关心这样的错误? 有哪些避免或预防的方法?

【问题讨论】:

  • 这就像一个 1 升的瓶子,当您尝试将超过 1 升的液体倒入其中时。
  • @mjv: ...更不用说在升瓶和夸脱瓶之间倒酒时遇到的错误(和混乱)...
  • @mjv 只是你的瓶子不会突然显得空了。
  • @mjv,虽然一些实现细节通常意味着当你的瓶子太满的那一刻,它会神奇地倒空自己,或者把自己倒过来,这取决于是否有人签名。 :P
  • 吹毛求疵,但是环绕 always 是整数溢出的行为吗?它被标记为“语言不可知论”。

标签: language-agnostic integer-overflow


【解决方案1】:

当您尝试表达的数字大于整数类型可以处理的最大数字时,就会发生整数溢出。

如果你试图用一个字节来表示数字 300,你就会出现整数溢出(最大值为 255)。两个字节中的 100,000 也是整数溢出(最大为 65,535)。

您需要关心它,因为数学运算不会像您预期的那样运行。如果整数溢出,A + B 实际上并不等于 A 和 B 的总和。

您可以通过不首先创建条件来避免它(通常是通过选择足够大的整数类型以防止溢出,或者通过限制用户输入以免发生溢出)。

【讨论】:

    【解决方案2】:

    解释它的最简单方法是用一个简单的例子。假设我们有一个 4 位无符号整数。 0 将是 0000,1111 将是 15。因此,如果您增加 15 而不是获得 16,您将绕回 0000,因为 16 实际上是 10000,我们不能用少于 5 位来表示它。尔格溢出...

    在实践中,数字要大得多,如果 int 有符号,它会在溢出时圈出一个很大的负数,但上述情况基本上就是这样。

    另一种看待它的方式是将其视为与汽车里程表在达到 999999 公里/英里后再次归零时发生的情况大致相同。

    【讨论】:

    • “小于 5 位”,而不是“小于 5 字节”。
    【解决方案3】:

    当您将整数存储在内存中时,计算机会将其存储为一系列字节。这些可以表示为一系列 1 和 0。

    例如,0 将表示为00000000(8 位整数),并且通常,127 将表示为01111111。如果在 127 上加一,这将“翻转”这些位,并将其交换为 10000000,但在 standard two's compliment 表示中,这实际上用于表示 -128。这会“溢出”值。

    对于无符号数,同样的事情会发生:255 (11111111) 加 1 会变成 100000000,但由于只有 8 个“位”,所以最终会变成 00000000,即 0。

    您可以通过对正确的整数大小进行适当的范围检查或使用为您进行适当的异常处理的语言来避免这种情况。

    【讨论】:

    • 10000000 在 2 的补码中是 INT_MIN(例如,1 个有符号字节为 -128)。 -1 是FFFFFFFF
    【解决方案4】:

    当操作使整数值大于其最大值时,会发生整数溢出错误。

    例如,如果您可以拥有的最大值是 100000,而您当前的值是 99999,那么加 2 将使其“溢出”。

    您应该注意整数溢出,因为数据可能会在不经意间被更改或丢失,并且可以使用更大的整数类型(请参阅大多数语言中的 long int)或使用将长数字字符串转换为非常大整数的方案来避免它们.

    【讨论】:

      【解决方案5】:

      溢出是指算术运算的结果不适合运算的数据类型。如果添加 255 + 1,则字节大小的无符号整数可能会溢出,因为结果 (256) 不适合一个字节的 8 位。

      如果浮点运算的结果太大而无法在浮点数据类型的指数或尾数中表示,则浮点数可能会溢出。

      当浮点运算的结果太而无法在给定的浮点数据类型中表示时,您还可以使用浮点类型进行下溢。例如,如果浮点数据类型可以处理 -100 到 +100 范围内的指数,并且您将一个值与 -80 的指数平方,结果将有一个大约 -160 的指数,这不适合给定的浮点数据类型。

      您需要注意代码中的上溢和下溢,因为它可能是无声的杀手:您的代码会产生不正确的结果,但可能不会发出错误信号。

      您是否可以安全地忽略溢出在很大程度上取决于您的程序的性质 - 从 3D 数据渲染屏幕像素对数字错误的容忍度要比财务计算大得多。

      溢出检查通常在默认编译器设置中关闭。为什么?因为在每次操作后检查溢出的附加代码需要时间和空间,这会降低代码的运行时性能。

      帮自己一个忙,至少在打开溢出检查的情况下开发和测试您的代码。

      【讨论】:

        【解决方案6】:

        来自wikipedia

        在计算机编程中,整数 当算术运算发生溢出 操作尝试创建一个数字 大于可以的值 在可用范围内表示 储存空间。例如,将可以表示的最大值加 1 构成整数溢出。这 在这些情况下,最常见的结果是 对于最不重要的 结果的可表示位是 存储(结果被称为包装)。

        您应该特别注意它,尤其是在为您的程序选择合适的数据类型时,否则您可能会遇到非常微妙的错误。

        【讨论】:

        • 这回答了什么,而不是为什么和如何
        【解决方案7】:

        来自http://www.first.org/conference/2006/papers/seacord-robert-slides.pdf

        整数溢出时发生整数溢出 增加超过其最大值或 下降到超过其最小值。 溢出可以有符号或无符号。

        P.S.:PDF 详细解释了溢出和其他整数错误情况,以及如何解决/避免它们。

        【讨论】:

          【解决方案8】:

          到目前为止,我想与所有其他答案有点相反,它们以某种方式接受蹩脚的破数学作为给定的。这个问题被标记为与语言无关,并且在大量语言中,整数永远不会溢出,所以这是我的讽刺回答:

          什么是整数溢出错误?

          计算黑暗时代的过时神器。

          我为什么要关心它?

          你没有。

          如何避免?

          使用整数不会溢出的现代编程语言。 (Lisp、Scheme、Smalltalk、Self、Ruby、Newspeak、Ioke、Haskell,任君挑选……)

          【讨论】:

            【解决方案9】:

            我发现在光盘上显示二进制补码表示非常有帮助。

            这是 4 位整数的表示。最大值为 2^3-1 = 7。

            对于 32 位整数,我们将看到最大值为 2^31-1

            2^31-1加1:顺时针加一,明显是-2^31,称为整数溢出

            参考:https://courses.cs.washington.edu/courses/cse351/17wi/sections/03/CSE351-S03-2cfp_17wi.pdf

            【讨论】:

              【解决方案10】:

              当您尝试将整数用于高于整数的内部结构由于使用的字节数而可以支持的值时,就会发生这种情况。例如,如果最大整数大小为 2,147,483,647,而您尝试存储 3,000,000,000,则会收到整数溢出错误。

              【讨论】:

              • 溢出是数学运算的产物,而不是赋值/存储。
              猜你喜欢
              • 1970-01-01
              • 2021-11-22
              • 1970-01-01
              • 1970-01-01
              • 2011-04-23
              • 1970-01-01
              • 1970-01-01
              • 2011-06-20
              • 1970-01-01
              相关资源
              最近更新 更多