3.11 编程练习
1.通过试验(即编写带有此类问题的程序)观察系统如何处理整数上溢、浮点数上溢和浮点数下溢的情况。
int类型(整数类型)占用4字节,范围为-2^ 31 ~ 2^31-1
即-2147483648 ~ 2147483647,
十六进制表示:0x80000000 ~ 0x7FFFFFFF。
float类型(单精度浮点数类型)占用4字节,
数值范围为 -3.4E+38 到 3.4E+38
#include <stdio.h>
int main(void)
{
int a = 2147483647;
float b = 3.4E38 * 100.0f;//p58页程序
float c = (-3.4e-38-10) / 10e100;
printf("%ld\n",sizeof(float));
printf("%ld\n",sizeof(int));
printf("%d %d %d\n", a, a+1, a+2); //整数上溢
printf("%e\n", b); //浮点数上溢
printf("%e\n", c); //浮点数下溢
return 0;
}
当计算导致数字过大,超过当前类型能表达的范围时,就会发生上溢(overflow)。对于整数溢出,如果是unsigned int类型的变量会从0开始,而int 类型的变量从-2147483648开始。
float类型的数以指数和位数部分来储存。存在这样一个数,它的指数部分是最小值,即由全部可用位表示的最小尾数值。该数字是float类型能用全部精度表示的最小数字。现在把它除以 2 。通常,这个操作会减小指数部分,但是假设的情况中,指数已经是最小值了。计算机只好把尾数部分的位向右移,空出第 1 个二进制位,并丢弃最后一个二进制数。这样虽然得到了结果,但是在计算过程中损失了原末尾有效位上的数字。这种情况叫做下溢(underflow)。C语言把损失了类型全精度的浮点值称为低于正常的(subnormal)浮点值。因此,把最小的正浮点数除以2将得到一个低于正常的值。如果除以一个非常大的值,会导致所有的位都为 0 。
注意,当变量溢出其相应类型所能表示的最大值时,系统并不会通知用户。因此,在编程时必须自己注意这类问题。