作者:阮一峰
日期:2010年6月 6日
1.
前几天,我在读一本C语言教材,有一道例题:
#include
void main(void){
int num=9;/* num是整型变量,设为9 */
float* pFloat=#/* pFloat表示num的内存地址,但是设为浮点数 */
printf("num的值为:%d\n",num);/* 显示num的整型值 */
printf("*pFloat的值为:%f\n",*pFloat);/* 显示num的浮点值 */
*pFloat=9.0;/* 将num的值改为浮点数 */
printf("num的值为:%d\n",num);/* 显示num的整型值 */
printf("*pFloat的值为:%f\n",*pFloat);/* 显示num的浮点值 */
}
运行结果如下:
num的值为:9
*pFloat的值为:0.000000
num的值为:1091567616
*pFloat的值为:9.000000
我很惊讶,num和*pFloat在内存中明明是同一个数,为什么浮点数和整数的解读结果会差别这么大?
要理解这个结果,一定要搞懂浮点数在计算机内部的表示方法。我读了一些资料,下面就是我的笔记。
2.
在讨论浮点数之前,先看一下整数在计算机内部是怎样表示的。
int num=9;
上面这条命令,声明了一个整数变量,类型为int,值为9(二进制写法为1001)。普通的32位计算机,用4个字节表示int变量,所以9就被保存为00000000 00000000 00000000 00001001,写成16进制就是0x00000009。
那么,我们的问题就简化成:为什么0x00000009还原成浮点数,就成了0.000000?
3.
根据国际标准IEEE 754,任意一个二进制浮点数V可以表示成下面的形式:
(1)(-1)^s表示符号位,当s=0,V为正数;当s=1,V为负数。
(2)M表示有效数字,大于等于1,小于2。
(3)2^E表示指数位。
举例来说,十进制的5.0,写成二进制是101.0,相当于1.01×2^2。那么,按