c语言中数据的存储2.0之浮点数的存储形式

浮点型在内存中的存储

int n=9;
   float* pfloat=(float*)&n;
   printf("n的值为%d\n",n);
  printf("n的值为%f\n",*pfloat);
  
  * pfloat= 9.0;
  printf("n的值为 %d \n",n);
  printf("* pfloat的值为:%f",* pfloat);
n的值为9
n的值为0.000000
n的值为 1091567616 
* pfloat的值为:9.000000

 为什么会出现这种情况,这是因为在内存中 浮点数 和 整形数 遵循着不同的存储法则

 首先我们先了解一下IEEE754标准

c语言中数据的存储2.0之浮点数的存储形式

 对于这个概念我们首先有一个大概的了解,下面将剩下的内容翻译为人话大致是

c语言中数据的存储2.0之浮点数的存储形式

v =(-1)^S *M * 2^E

 1.  (-1)^S表示符号位 ,当s=0,v正,s=1,v负

2.     M代表有效数字,大于 1 小于2

3   2^E 表示指数位

以9.0为例

//   9.0
//   1001.0
//   (-1)^0  *  1.001 *  2^3
//      S=0   M- 1.001  E=3

 

c语言中数据的存储2.0之浮点数的存储形式

c语言中数据的存储2.0之浮点数的存储形式

 

IEEE754 规定

(1) 因为 M均可表示为 大于1小于2的数字, 所在存储中对于 小数点前一位的1省略,可以提高一位精度表示

 (2)     而对于 E 而言 ,首先E是一个无符号数, 当E为8位时 取值范围为0-255 ;当E为11位时取值范围为0 - 2047.

 但是 对于科学计数法表达形式,  指数可负 ,

所以 IEEE754规定,存入内存中的E需要加上一个中间量来保证它的非负性, 

 对于 8位的E,中间值为 127; 对于11位的E,这个中间数是1023;

例如 2^10 , 存储的值 = 10+127=137 即为 10001001

//float a=5.5; 
// 101.1
// (-1)^0  * 1.011^2^2 
//  S=0  M=1.011 E=2
//0 10000001 01100000000000000000000
  (2 +127)  
// 在内存化为16进制更为普遍  0x40b00000
 

 

 而E 取出来时又分为三种情况

当E不为全0或不为全1时,如上图单精度,指数E-127得到真实值  ,M加上1取出即为真实值

 当E为全0时,这是对于它已经加上127后得到的结果,1.xxx*2^-127   几乎接近于0,所以

直接  规定指数等于1-127(1-1023即为真实值,有效位数M不再加上第一位的1,而是还原为0.xxx的小数,其实就是表示0

当E为全1时,表示正负无穷大的情况 

 

int n=9;
//  00000000 00000000 00000000 00001001 
   float* pfloat=(float*)&n;
   printf("n的值为%d\n",n);
  printf("n的值为%f\n",*pfloat);
//  0 00000000 00000000000000000001001 
//(-1)^0*0.00000000000000000001001*  2 ^(-126)
// %f 打印 小数点后六位 0.000000
  
  * pfloat= 9.0;
// 1001.0
//(-1)^0  * 1.001*2^3
// 0 10000010 00100000000000000000000

  printf("n的值为 %d \n",n);
//01000001000100000000000000000000  正数的原反补相同 转化成2进制即可得到结果
  printf("* pfloat的值为:%f",* pfloat);
上一篇:校验代码为 6054 坏块修复


下一篇:C语言之——scanf函数