整数溢出

编辑
本词条由“匿名用户” 建档。
在计算机编程中,当算术运算试图创建超出可以用给定位数表示的范围的数值时,就会发生整数溢出 - 高于最大值或低于最小可表示值。 最常见的溢出结果是存储结果的最低有效位; 据说结果环绕最大值(即模基数的幂,在现代计算机中通常是两个,但有时是十个或另一个基数)。 溢出条件可能会产生导致意外行为的结果。 特别是,如果未预料到这种可能性,溢出可能会危及程序的可靠性和安全性。 对于某些应...

整数溢出

编辑

计算机编程中,当算术运算试图创建超出可以用给定位数表示的范围的数值时,就会发生整数溢出 - 高于xxx值或低于最小可表示值。

最常见的溢出结果是存储结果的最低有效位; 据说结果环绕xxx值(即模基数的幂,在现代计算机中通常是两个,但有时是十个或另一个基数)。

溢出条件可能会产生导致意外行为的结果。 特别是,如果未预料到这种可能性,溢出可能会危及程序的可靠性和安全性。

对于某些应用程序,例如定时器和时钟,溢出时回绕可能是可取的。 C11 标准规定,对于无符号整数,模换行是定义的行为,术语溢出从不适用:涉及无符号操作数的计算永远不会溢出。

在某些支持饱和算法的处理器上,如图形处理单元 (GPU) 和数字信号处理器 (DSP),溢出的结果将被限制,即设置为可表示范围内的最小值或xxx值,而不是环绕。

产地

编辑

处理器的寄存器宽度决定了可以在其寄存器中表示的值的范围。 尽管绝大多数计算机可以对内存中的操作数执行多精度算术运算,允许任意长的数字并避免溢出,但是寄存器宽度限制了可以使用的数字的大小(例如,加或减) 每个操作一条指令。 无符号整数的典型二进制寄存器宽度包括:

  • 4 位:xxx可表示值 24 − 1 = 15
  • 8 位:xxx可表示值 28 − 1 = 255
  • 16 位:xxx可表示值 216 − 1 = 65,535
  • 32 位:xxx可表示值 232 − 1 = 4,294,967,295(截至 2005 年个人计算机最常见的宽度),
  • 64 位:xxx可表示值 264 − 1 = 18,446,744,073,709,551,615(个人计算机中央处理器 (CPU) 最常见的宽度,截至 2021 年),
  • 128 位:xxx可表示值 2128 − 1 = 340,282,366,920,938,463,463,374,607,431,768,211,455

当无符号算术运算产生的结果大于上述 N 位整数的xxx值时,溢出会将结果缩减为 2 的 N 次方模,仅保留结果的最低有效位并有效地导致回绕。

特别是,两个整数相乘或相加可能会得到一个意外小的值,而从一个小整数中减去可能会导致一个大的正值回绕(例如,8 位整数相加 255 + 2 结果为 1,这 是 257 mod 28,类似地,减法 0 − 1 的结果是 255,即 −1 的二进制补码表示)。

这样的回绕可能会导致安全损害——如果溢出的值被用作分配给缓冲区的字节数,缓冲区将被分配到意想不到的小,可能导致缓冲区溢出,根据缓冲区的使用,可能会在 turn 导致任意代码执行。

如果变量具有带符号的整数类型,则程序可能会假设变量始终包含正值。 整数溢出会导致值回绕并变为负数,这违反了程序的假设并可能导致意外行为(例如,8 位整数加法 127 + 1 的结果为 −128,一个二的 128 的补码)。 (这个特定问题的解决方案是使用无符号整数类型来表示程序期望并假定永远不会为负的值。)

标志

编辑

大多数计算机都有两个专用处理器标志来检查溢出情况。

当加法或减法的结果(将操作数和结果视为无符号数)不适合给定的位数时,会设置进位标志。 这表示从最高有效位进位或借位的溢出。

整数溢出

紧随其后的带进位加法或带借位减法运算将使用此标志的内容来修改包含多字值较高部分的寄存器或内存位置

当对有符号数的运算结果不具有可以从操作数的符号预测的符号时设置溢出标志,例如,将两个正数相加时的结果为负数。 这表明发生了溢出,以二进制补码形式表示的带符号结果不适合给定的位数。

定义的变化和歧义

编辑

对于无符号类型,当运算的理想结果超出该类型的可表示范围并且返回结果是通过包装获得的,则通常将此事件定义为 overf。

内容由匿名用户提供,本内容不代表vibaike.com立场,内容投诉举报请联系vibaike.com客服。如若转载,请注明出处:https://vibaike.com/195916/

(1)
词条目录
  1. 整数溢出
  2. 产地
  3. 标志
  4. 定义的变化和歧义

轻触这里

关闭目录

目录