用C语言判断一个机器字节序列的存储模式是大端还是小端存储以及浮点型在内存中的存储

首先,我们来思考一下,为什么会有大小端模式之分呢?
我们知道,在计算机系统中,是以字节为存储单位而存储的,每一个地址都对应着一个字节(8bit)。而对于有些类型的变量大小不是一个字节。类如,在32位的系统下,int,float,long,都是4字节大小,而一个地址中就无法容纳。所以就存在如何安放其它字节的问题。就导致了大端存储模式和小端存储模式
大端:数据低位保存在内存的高地址中,而数据的高位,保存在内存的地地址中。
小端:数据低位保存在内存的低地址中(小小小),数据高位保存在内存的高地址中。
下面是如何通过代码来判断一个机器的存储模式:

#include<stdio.h>
#include<windows.h>
int Endian()
{
    int i = 1;
    return (*(char *)&i);//先把int*强转为char*然后再解引用
}
int endian()
{
    union u
    {
        int i;
        char j;
    }u;
    u.i = 1;
    return u.j ;
}
int main()
{
    int ret = Endian();
    if(ret == 1)
    {
        printf("该电脑以小端存储。\n");
    }
    else
    {
        printf("该电脑以大端存储。\n");
    }
    system("pause");
    return 0;
}

这里写图片描述
所以我的电脑就是小端的存储模式。^_^

了解在计算机的内部浮点数的表示方法:

根据国际IEEE754,对于一个二进制浮点数可以表示为: (-1)^S*M*2^E
(-1)^S:表示符号位,当s=0,表示正数;当s=1时,表示负数.
M表示有效数字,[1,2)之间.
2^E表示指数位.
比如:十进制的7.0——二进制:111.0——相当于:1.11*2^2

S = 0;M = 11;E = 2;

十进制的-7.0——二进制:-111.0——相当于:-1.11*2^2;

S = 1;M = 11;E = 2;

国际标准规定:对于32位的浮点数,第一位是符号位,紧接着8位是指数(E)位,剩下的23位是有效数字(M)位。
这里写图片描述
对于64位的浮点数指数位有11位,有效数字位为52位。
这里写图片描述

但是,在计算机内部中保存M(有效数字位)时,默认数的整数位为1,所以就可以省掉这个相同的整数位,也就是说只保存后面的××××××部分。比如保存1.01时,只保存01,等到读取的时候,再把第一位的1加上。所以,这样就可以节省1位的有效位,也就是说可以保存24位的有效数字。

对于科学计数法的指数E,在计算机中时这样存储的。

E:一个无符号的整数。

当E为8位时,取值范围:0~255
当E为11位时,取值范围:0~2047
但是,在正常的表示中,E是可以为负的。因此,为了解决这个问题,IEEE规定,在内存中E的真实值必须再加一个中间值。E位8时,中间值位127;E为11时,中间值为1023.

比如:2^10中E = 10.表示为32位的浮点数时,必须保存为10 + 127 = 137.二进制序列为:10001001.

下面分情况讨论E:
①E不全为0或不全为1
E真实值的计算方法:E的计算值减去127(64位减去1023)。再把有效数字的第一位1加到小数前。
比如:0.5(1/2)二进制的形式为0.1,但是对于浮点数的存储,第一位必须位1,所以,表示为:1.0*2^(-1),E就为(-1)+ 127 = 126,表示为:01111110,而1.0去掉整数位1后,就是全零。所以0.5的二进制存储为:

0   01111110    00000000000000000000000

②E全为0
E:1 - 127(或1023)即为真实值,这时,有效数字位不再加第一位的整数位1,而是还原为小数的表示形式(0.××××)。这样的目的时为了区分正负0以及接近于0的很小的数字。
③E全为1
当有效数字位M全为0时,就表示正负无穷大。
下面我们通过一道题来巩固一下:

    int n = 9;
    float *p = (float*)&n;
    printf("n:%d\n",n);
    printf("*p:%f\n",*p);

    *p = 9.0;
    printf("n:%d\n",n);
    printf("*p:%f\n",*p);

这里写图片描述
解释一下为什么变成浮点数就变成了0.000000.从浮点数的存储形式,我们可以得出:9—–>1001。S位:0;E:00000000;M:00000000000000000001001.所以9变成浮点数后存储为:

0 00000000 00000000000000000001001
=====>(-1)^0*2^(-126)*0.00000000000000000001001 = 1.001*2^(-146)

所以用十进制打出来就是:0.000000
还有:当浮点数为9.0时,为什么打印出来是一个很大的数???
首先,来剖析9.0再内存中的存储:S:0;E:3 + 127 = 130;M:001

0 10000010 00100000000000000000000

所以上面的这个二进制序列用十进制的形式打印出来就是一个很大的数了。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值