大端模式Big Endian和小端模式Little Endian以及浮点数在内存中的存储

大端模式和小端模式存放数据的区别很简单:大端模式先存放数据的高位字节,小端模式先存放数据的低位字节。

比如 int a=0x01234567,a所占的四个字节16进制标示:01 23 45 67。


在Linux系统中,使用命令:

```bash

lscpu

```

输出:

```bash

Architecture:          x86_64

CPU op-mode(s):        32-bit, 64-bit

Byte Order:            Little Endian

CPU(s):                8

On-line CPU(s) list:   0-7

Thread(s) per core:    1

Core(s) per socket:    1

CPU socket(s):         8

NUMA node(s):          1

Vendor ID:             GenuineIntel

CPU family:            6

Model:                 13

Stepping:              3

CPU MHz:               2499.998

BogoMIPS:              4999.99

Hypervisor vendor:     KVM

Virtualization type:   full

L1d cache:             32K

L1i cache:             32K

L2 cache:              256K

L3 cache:              15360K

NUMA node0 CPU(s):     0-7

```

注意其中`Byte Order:  Little Endian`。表示当前运行x86 Intel计算机使用的是`Little Endian`

写一个函数判断机器是不是大端模式:

bool isBigendian()
{
    int a=1;
    char *pa=(char *)&a;
    if((*pa)==0x01)
    {
        return false;
    }
    else
    {
        return true;
    }
}

网络传输中使用`Big Endian`

文件存储会不会受字节序影响呢?

如果是纯ASCII文件,那么大小端无所谓,因为每个字符只有一个字节。unicode文件,就要看保存文件的编码了,比如utf-8编码会在文件开头的两个字节里规定好使用什么字节序。

大小端字节序那个好呢?

大小端的概念来源于《格列夫游记》中的关于从大头敲开鸡蛋还是从小头敲开的斗争。就像小说里无意义的争斗一样,大小端字节序没有好坏之分。



浮点数在内存中怎么存储?

我们知道,浮点数分为单精度(float)和双精度(double)两种。float类型占4byte内存,double类型占8byte内存。浮点数的二进制存储标准遵循IEEE 754标准。下面定义一个浮点数,然后输出它每个字节内容。

void showbytes(unsigned char *p,int len) // 注意这个p指针类型必须是unsigned char,后边才能表示出真实的字节内容。要不然会进行符号位扩展。
{
    for(int i=0;i<len;i++)
    {
        printf("%x ",*(p++));
    }
    printf("\n");
}

int main()
{
    if(isBigending())
    {
        cout<<"this system is big endian"<<endl;
    }
    else
    {
        cout<<"this system is  little endian"<<endl;
    }

    float f=1.1;
    double d1=1.1;
    double d2=f;// f类型提升
    cout<<"f store as :"<<endl;
    showbytes((unsigned char *)&f,sizeof(f));
    cout<<"d1 store as :"<<endl;
    showbytes((unsigned char *)&d1,sizeof(d1));
    cout<<"d2 store as :"<<endl;
    showbytes((unsigned char *)&d2,sizeof(d2));

}

运行结果:



由于是小端模式,所以f存储到内存里后内存里内容为3f 8c cc cd 二进制:0011 1111 1000 1100 1100 1100 1100 1101

同理,d1在内存里的内容为3f f1 99 99 99 99 99 a9 二进制:0011 1111 1111 0001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1010 1001

同理,d2在内存中的内容为3f f1 99 99 a0 00 00 00二进制:0011 1111 1111 0001 1001 1001 1001 1001 1010 0000 0000 0000 0000 0000 0000 0000

IEEE754标准规定单精度浮点数:1位符号位,8位阶码,23位尾数。那么f的:

符号位:0

阶码:01111111,十进制阶码就是0

尾数:000 1100 1100 1100 1100 1101

转换成十进制约为1.1


IEEE754标准规定双精度浮点数:1位符号位,11位阶码,52位尾数。那么d1的:

符号位:0

阶码:011 1111 1111,十进制阶码就是0

尾数:0001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1010 1001

转换成十进制约为1.1


那么d2的:

符号位:0

阶码:011 1111 1111,十进制阶码就是0

尾数:0001 1001 1001 1001 1001 1010 0000 0000 0000 0000 0000 0000 0000

转换成十进制约为1.1


可以发现,d2的尾数就是f的尾数。f类型提升后低位填充0,所以精度并没有提高。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值