深入谈谈整型、浮点型在内存中的存储方式

30 篇文章 0 订阅
19 篇文章 0 订阅

一、正整型

 

正整型,没什么好说的,就是补码存储方式,正数的补码和原码相同,即先转换为二进制,然后高位扩展0,一直填充至32位……
比如:5这个数的存储方式如下
先转换为二进制:101
因为只有3位,所以前面填充29个0,即 00000000 00000000 00000000 00000101
二、负整型
负整型,跟正整型一样,也是补码存储方式,不过负数的补码计算方式是取绝对值的二进制,按位取反再加1
比如:-5这个数
先取绝对值,即5,即 00000000 00000000 00000000 00000101
然后按位取反:11111111 11111111 11111111 11111010
再加1:即 11111111 11111111 11111111 11111011

 

 

三、正浮点型

浮点型中有两种,一种是4Byte的float型,一种是8Byte的double型,这两种计算方式都一致,只是有点点区别
1、float型:
float型是遵循IEEE R32.24规范,即1位符号位、8位阶码、23位尾数
具体计算方式是先用科学计数法表示出该数的二进制,然后计算出阶码值,最后把尾数 补足23位,依此存储
比如125.5这个数
先看整数部分,125表示成二进制是1111101,(整数转换二进制是除二取余)
再看小数部分,0.5表示成二进制是0.1,(小数转换二进制是乘二取整)
所以125.5用二进制表示就是1111101.1,转换成科学计数法就是1.1111011 x 2^6(阶数为6)
但是这里的阶码是用移码的形式表示,float型的偏置量是127,于是6+127=133,即10000101

阶码:这里阶码采用移码表示,对于float型数据其规定偏置量为127,阶码有正有负,对于8位二进制,则其表示范围为-128-127,double型规定为1023,其表示范围为-1024-1023。比如对于float型数据,若阶码的真实值为2,则加上127后为129,其阶码表示形式为10000010

尾数:有效数字位,即部分二进制位(小数点后面的二进制位),因为规定M的整数部分恒为1,所以这个1就不进行存储了。


这里前面的9位就出来了,因为是正数,所以符号位为0,阶码为10000101
后面的尾数就是1111011,在后面补0,凑齐23位,即 1111011 00000000 00000000(因为科学计数法的整数部分总是为1,所以,这个1不用存储)
所以125.5的存储方式为 0 10000101 11110110000000000000000
即: 01000010 11111011 00000000 00000000
2、double型
double型跟float型计算方式类似,不过区别在于double型遵循IEEE R64.53规范
a、double的符号位是1位,阶码为11位,尾数为52位
b、double的偏置量是1023,而float是127
四、负浮点型
和上面一样,不过就是符号位用1表示,就这点小区别
五、验证方式
有两种验证方式,一种是用联合体的方法、一种是强制类型转换方法
1、联合体法:
可以定义一个联合体,比如
union data
{
float a;
char array[4];
};
那么可以对a赋值,然后依次输出数组array的各个元素,这样就可以验证
2、强制类型转换法:
float a;
char *p=(char *)&a;
这样,将a的地址强制转换为指向字符类型之后,赋值给指针p,后续再依次输出*p、*(p+1)、*(p+2)、*(p+3)的值,也可以进行验证

例:

 

#include
int main(int argc, char *argv[])
{
float a= 0.5;
char *p = (char *)&a;
printf("%d.\n",*(p+0));
printf("%d.\n",*(p+1));
printf("%d.\n",*(p+2));
printf("%d.\n",*(p+3));
return 0; 
 
}

int main(int argc, char *argv[])
{
float a= 0.5;
char *p = (char *)&a;
printf("%d.\n",*(p+0));
printf("%d.\n",*(p+1));
printf("%d.\n",*(p+2));
printf("%d.\n",*(p+3));
return 0; 

}
 

 

 

分析:0.5的二进制形式为0.1,由于规定正数部分必须为1,将小数点右移1位,则为1.0*2^(-1);

0 01111110 00000000000000000000000

符号位 阶码转化为二进制(-1+127) 小数部分

裁剪:

00111111

00000000

00000000

00000000

结果:

 

 

 

 

 

 

 

 

 
--------------------- 
版权声明:本文为CSDN博主「种瓜大爷」的原创文章,遵循CC 4.0 by-sa版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/czg13548930186/article/details/53433828

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值