C编程中的算术下溢和上溢是什么意思?
溢出
来源于http://en.wikipedia.org/wiki/Arithmetic_overflow:
当计算产生的结果大于某个给定寄存器或存储位置可以存储或表示的大小时,就会发生溢出。
例如:
uint32_t x = 1UL << 31;
x *= 2; // Overflow!
请注意,正如下面@R在评论中提到的那样,C标准建议:
涉及无符号操作数的计算永远不会溢出,因为不能由结果无符号整数类型表示的结果将对比较类型的最大值加一进行取模。
当然,这是一个相当特殊的“溢出”定义。大多数人会将模重复(即环绕)称为“溢出”。
下溢
来自http://en.wikipedia.org/wiki/Arithmetic_underflow:
计算机程序中可能发生条件,即浮点运算的实际结果在目标数据类型中不能表示的最小值的幅度(即更接近于零)小。
因此,例如:
float x = 1e-30;
x /= 1e20; // Underflow!
int是C语言中最常见的数据类型,它是一个32位的数据类型。这意味着每个int在内存中被分配了32位。如果我有一个变量
int a = 2;
在内存中,一个32位的二进制数可以表示为:00000000000000000000000000000010。
如果你有两个二进制数:
10000000000000000000000000000000
和
10000000000000000000000000000000,
它们的和将是100000000000000000000000000000000,长度为33位。然而,计算机只取最低的32位,其余的都是0。在这种情况下,计算机认为和大于32位所能存储的范围,会出现溢出错误。
下溢基本上是相反方向发生的同样事情。C语言使用的浮点标准允许小数点后保留23位;如果数字的精度超过了这个范围,它将无法存储这些位。这会导致下溢错误和/或精度损失。
int
不是一个32位数据类型。 - Philip下溢仅取决于给定的算法和输入数据,因此程序员没有直接控制权。另一方面,溢出取决于程序员对每个堆栈保留的内存空间量的任意选择,这种选择确实会影响溢出发生的次数。
unsigned char x = 0; x -= 1;
这算作下溢吗? - Gamal Othman