什么是C中的算术下溢和溢出?

时间:2011-06-15 15:15:50

标签: c math integer-overflow

C编程中算术下溢和溢出是什么意思?

4 个答案:

答案 0 :(得分:28)

<强>溢出

来自http://en.wikipedia.org/wiki/Arithmetic_overflow

  

a时发生的情况   计算产生的结果是   比a更大   给定注册或存储位置即可   存储或代表。

所以,例如:

uint32_t x = 1UL << 31;
x *= 2;  // Overflow!

请注意,正如@R在下面的评论中提到的那样,C标准建议:

  

涉及无符号的计算   操作数永远不会溢出,因为a   无法表示的结果   得到的无符号整数类型是   减少模数是一个数   大于最大值   可以用结果来表示   类型。

当然,这是“溢出”的一个相当特殊的定义。大多数人会将模数减少(即环绕)称为“溢出”。

<强>下溢

来自http://en.wikipedia.org/wiki/Arithmetic_underflow

  

计算机程序中的条件   当真正的结果发生时   浮点运算较小   幅度(即接近零)   比可表示的最小值   作为正常的浮点数   目标数据类型。

所以,例如:

float x = 1e-30;
x /= 1e20; // Underflow!

答案 1 :(得分:7)

计算机仅使用0和1来表示数据,以便可以表示的值范围受到限制。许多计算机使用32位来存储整数,因此在这种情况下可以存储的最大无符号整数是2 ^ 32 -1 = 4294967295.但是第一位用于表示符号,因此,实际上,最大的值是2 ^ 31 - 1 = 2147483647。

超出允许范围的整数需要的位数多于可存储的位数称为溢出。

同样,对于实数,指数太小而无法存储会导致下溢。

答案 2 :(得分:-3)

int,C中最常见的数据类型是32位数据类型。这意味着每个in​​t在内存中被赋予32位。如果我有变量

int a = 2;

实际上将在内存中表示为32位二进制数: 00000000000000000000000000000010。

如果您有两个二进制数字,例如

10000000000000000000000000000000

10000000000000000000000000000000,

它们的总和将是100000000000000000000000000000000,即33位长。但是,计算机只接受32个最低有效位,它们都是0.在这种情况下,计算机识别出总和大于32位存储的总和,并给出溢出错误。

下溢基本上是相反方向发生的事情。用于C的浮点标准允许小数点后的23位;如果数字的精度超过这一点,它将无法存储这些位。这会导致下溢错误和/或精度损失。

答案 3 :(得分:-4)

下溢完全取决于给定的算法和给定的输入数据,因此程序员没有直接控制。另一方面,溢出取决于程序员对每个预留的内存空间量的任意选择。堆栈,这个选择确实会影响溢出的次数