数据在内存中的存储2

目录

前言

一、浮点数的表示方法

二、浮点数在内存中的存储

1、符号位S

2、有效数字M

3、指数部分E

三、大小端存储模式

1、什么是大端和小端存储模式

2、写一个函数判断当前机器的存储模式


前言

Hello,小伙伴们我又来了,今天我们继续数据在内存中的存储方式部分的学习。如果觉得不错的话,不要忘了点赞,收藏评论哦,大家的支持就是我继续更新的动力,万分感谢!!

我们都知道整型数据在内存中是以补码形式存储的,并且我们可通过原码、反码和补码之间的关系很容易地进行计算。
那么浮点数在内存中又是如何存储的呢?

一、浮点数的表示方法

关于浮点数的表示方法,许多都是标准规定的,不必深究。

根据国际标准IEEE(电气和电子工程协会) 754,任意一个二进制浮点数V可以表示成下面的形式:

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

其中:
(-1) ^ S 表示符号位,当S=0,V为正数;当S=1,V为负数。
M 表示有效数字,大于等于1,小于2。
2 ^ E 表示指数。

注:
1、这里的有效数字范围是[1,2),可类比十进制中有效数字的范围是[1,10)。
2、指数部分以2为底数,类比十进制中指数部分以10为底数。

例如十进制中的5.0,写成二进制浮点数是101.0,用该形式表示就是(-1) ^ 0 * 1.01 * 2 ^ 2
(其中S = 0, M = 1.01, E = 2)

又如十进制中的-5.5,写成二进制浮点数是101.1(此处小数点后的第一位权重是2 ^(-1),也就是0.5,所以此处是1),用该形式表示就是(-1) ^ 1 * 1.011 * 2 ^ 2
(其中S = 1, M = 1.011, E = 2)

二、浮点数在内存中的存储


根据IEEE754标准规定:
对于32位的浮点数(float型),最高的一位是符号位S,接下里8位是指数E,剩下的23位为有效数字M。
对于64位的浮点数(double型),最高的1位是符号位S,接着的11位是指数E,剩下的52位为有效数字M。

1、符号位S


对于符号位S,只有0和1两种情况,分别表示正和负,此处不多赘述

2、有效数字M


对于有效数字M,由于M的范围是[1,2),也就是说M的整数部分一定为1,所以IEEE754标准规定:在计算机内部保存M时,默认这个数的第一位总是1,因此可以被舍去,只保存后面的小数部分

比如保存1.01的时候,只保存小数部分01,而将整数部分的 1舍去,等到读取的时候,再把第一位的1加上去。这样做的目的,是节省1位有效数字。32位浮点数留给M只有23位,将第一位舍去后,就可以保存24位有效数字。

3、指数部分E


对于指数部分E,情况就比较复杂。

(1)指数部分E是一个无符号整数(unsigned int),如果E为8位(32位浮点型),那么E能表示的范围是0 ~ 255;如果E为11位(64位浮点型),那么E能表示的范围是0 ~ 2047。

那么问题来了,这个指数E显然可以为负,但unsigned int的类型使E为非负数,所以IEEE754标准规定,存入内存中时,真实的指数必须加上一个中间值(对于8位的E,这个中间值是127,对于11位的E,这个中间值是1023)。

如一个32位浮点数的E = 3,那么在存入内存中时要加上127变为130后再换算成二进制1000 0010后存储

(2)E不全为0或不全为1

下面以上文的5.0和-5.5为例讲解。

对于浮点数5.0:
S = 0
M = 1.01 需将整数部分的1去掉,然后把小数部分的01存储,后面多余的位用0补齐
E = 2 需加上127变为129并转换为2进制后存储
则5.0表示为2进制为0 10000001 01000000000000000000000
在内存中以16进制展示,即40 a0 00 00


图片中字节反向涉及到大端存储和小端存储,具体内容见下文。

对于浮点数-5.5:
S = 1
M = 1.011 需将整数部分的1去掉,然后把小数部分的011存储
E = 2 需加上127变为129并转换为2进制后存储
则-5.5表示为2进制为1 10000001 01100000000000000000000
在内存中一般以16进制展示,即c0 b0 00 00


(3)E全为0时

由于E加上后127为全0,也就是说E的真实值为-127,即该浮点数指数部分是2 ^ (-127),显然这是一个极小的数,此时有效数字M不再加上第一位的1,而是还原为以0为整数的小数。这样做是为了表示±0,以及接近于0的很小的数字。

(4)E全为1时
由于E加上后127为全1,也就是说E的真实值为128,即该浮点数指数部分是2 ^ (128),显然这是一个极大的数,此时表示正负无穷大(正负号由S决定)

(3)(4)中以32位浮点数为例,64位浮点数同理

三、大小端存储模式


1、什么是大端和小端存储模式


大端(存储)模式:是指数据的低位保存在内存的高地址中,而数据的高位,保存在内存的低地址中。
小端(存储)模式:是指数据的低位保存在内存的低地址中,而数据的高位,,保存在内存的高地址中。

举个例子:正数1在内存中的16进制形式为00 00 00 01

2、写一个函数判断当前机器的存储模式


由上面的例子可知,如果a = 1, 那么&a后的第一个字节不同(小端存储模式为1,大端存储模式为0),又知char* 类型的指针在访问内存是权限是一个字字节,所以用char* 访问a后如果结果为1,则为小端存储模式,若结果为0,则为大端存储模式。

用其他数也可以,只要最低的一个字节和最高的一个字节表示的数不同即可,此处用1仅是为了简便

int check_sys()
{
    int a = 1;
    char* pa = (char*)&a;
    //注意强制类型转换
    int ret = *pa;
    //解引用拿到a的第一个字节
    return ret;
    //返回1为小端,返回0为大端
}
int main()
{
    int ret = check_sys();
    if (ret == 1)
    {
        printf("小端\n");
    }
    else
    {
        printf("大端\n");
    }
    return 0;
}

我当前的机器是小端存储模式。

check_sys函数也可简化为如下代码:

int check_sys()
{
    int a = 1;
    return *(char*)&a;
}



感谢阅读,如有错误请批评指正
————————————————

                            版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
                        
原文链接:https://blog.csdn.net/weixin_51983604/article/details/113619868

  • 42
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 26
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值