float和double变量的内存布局

转载:

浮点数在c/c++以及java中的内存布局遵循IEEE标准的,首先看一下IEEE所规定的存储的方式:

符号位指数位小数部分指数偏移量

单精度浮点数1 位[31]8位 [30-23]23位 [22-00]127

双精度浮点数1 位[63]11 位[62-52]52 位[51-00]1023

解释一下,首先float变量按上述标准是4个字节,,其中最高位为符号位,1代表此浮点数为负数,0代表正数,接下来的8位为指数位,范围0~255,,IEEE规定了一个偏移量127,指数位的值减去127为小数的偏移。低23位为小数部分,这23位是来描述浮点数的值,偏移为0的情况下,这23位数是一个浮点数的小数部分,也就是说位于小数点的右边。比如0x3fc00000符号位:0 ->说明是正数。 指数位:011 1111 1 –>偏移0小数位:100 0000 0000 0000 0000 0000,–>1.10000000000000000000000为1.5(乘二取整数)而按照规定,小数点前还隐含包括1,而这个1是不储存的,所以小数位实际是1.5,当偏移大于0时,小数点向右偏移相应的值,反之向左偏移相应的值。以上就是IEEE的存储的基本原理,现在验证下,加深印象

#include<iostream>intmain(){*p=0;p++;*p=0;p++;*p=0xc0;p++;*p=0x3f;cout<<a<<endl;}//输出1.5

0x40c00000符号位:0 ->说明是正数。 指数位:100 00001 –>偏移2

小数位:100 0000 0000 0000 0000 0000,由于偏移为2,1.100 0000 0000 0000 0000 0000变成了110.0 0000 0000 0000 0000 0000 所以0x40c00000值为6,同理0x3f400000值为0.75.类似的我们可以明白double变量的内存布局了。由于小数位的计算方式比如11.11111…在计算时为1*2^1+1*2^0+1*2^(-1)+1*2^(-2)….可以看出在表示小数时,flaot的值不是连续的,事实上浮点数,以IEEE标准所能精确表示的仅仅是其中的一部分。例如0.3,就不能被float所精确表示,如下面代码:

#include<iostream>intmain(){cout.precision(20);{}cout<<a<<endl;}

可以算出float所能精确表示的个数,32位每位两个有限的状态~~~~~了解了float布局,相应的下面代码问题的原因也就找到了~~~~

#include<iostream>intmain(){cout<<*p<<endl;//为什么输出的不是2cout<<a<<endl;}

当遗忘变成另一种开始,淡了回忆,痛最真实…

float和double变量的内存布局

相关文章:

你感兴趣的文章:

标签云: