文章目录
一、大、小端是什么?
大、小端即为大端存储和小端存储,是以字节为单位讨论
大端(字节序)存储:数据的低位保存在内存的高地址中,数据的高位保存在内存的低地址中
小端(字节序)存储:数据的低位保存在内存的低地址中,数据的高位保存在内存的高地址中
1.数据的低位和高位
int b=1234//4为个位,就是低位,1为千位,即为高位
int a=0x11223344//44为一个字节,是低位;11为高位
//a为16进制的数,一个16进制位为4个比特位,1byte=8bit,所以一个字节可以放两个16进制位
2.数据在内存中的存储
假如内存地址如下图所示:
大端字节序存储如下图:
小端字节序存储如下图:
3.检测本地机器大小端例子
#include<stdio.h>
int main()
{
int a = 1;//0x00000001
char* check = (char*)&a;
if (1 == *check)
{
printf("小端\n");
}
else
{
printf("大端\n");
}
return 0;
}
二、浮点型在内存中的存储
1.存放规则
对于十进制数,例如123.456,其科学计数法表示和权重表示如下:
科学计数法:123.456=1.23456x10^(2)
对应权重表示:123.456=1x10^(2)+2x10^(1)+3x10^(0)+4x10^(-1)+5x10^(-2)+6x10^(-3)
对任意一个二进制浮点数R,根据IEEE754标准,都可写成如下形式,类似整数权重表示:
R=(-1)^S*M*2^E
(-1)^S表示符号位,当S=0,R为正数;当S=1,R为负数
M表示有效位数,取值范围1<=M<2,类似十进制的1~9
2^E表示指数位
举例,对于十进制的5.5,其二进制形式:
5.5=1*2^(2)+0*2^(1)+1*2^(0)+1*2^(-1)=101.1=1.011*2^(2)=(-1)^0*1.011*2^2
S=0;M=1.011;E=2
2.存储模型
32位浮点数,最高的一个比特位为符号位S,然后是8位指数位E,剩下23位为有效数M,如下图:
64位浮点数,最高的一个比特位为符号位S,然后是11位指数位E,剩下52位为有效数M,如下图:
3.特殊说明
1.有效数字M
对于M,因为1<=M<2,即M=1.xxxx,为了使M的位数尽可能多,默认存储时将1舍去;对于32位浮点数为例,M只有23位,舍去1,则有24位有效数字
2.指数E向内存存放
E是无符号整数,对于8位的E,其范围0~255;对于11位的E,其范围0-2047,但是E会有负值,因此规定存入内存时E需要加一个中间数,对于8位E,中间数为127,对于11位E,中间数位1023,例如2^5,存为32位浮点数时,5+127=132,即10000100
3.指数E从内存取出
3.1指数E不全为0或不全为1
指数E的计算值减去127(或1023),得到真实值,再将有效数字M前加上舍去的1
3.2指数E全为0
当初始E加上127(或1023)后全为0,说明初始E小于等于-127(或-1023);则R=1.xxx*2(-127),无限接近0
3.3指数E全为1
当初始E加上127(或1023)之后全为1,说明初始E大于等于128(或1024);则R=1.xxx*2(128),无限大
3.完整的存取过程
32位浮点数存放:
R=5.5
R=5.5=101.1=(-1)^(0)*1.011*2^(2)
S=0,M=1.011,E=2
32位存储形式:E+127=2+127=129=10000001
0 10000001 01100000000000000000000
符号位S 指数位E 有效位M,只存1.xx后的x,不够23位补0
0100 0000 1011 0000 0000 0000 0000 0000 对应16进制其结果为:0x 00 00 b0 40 (小端存储)
32位浮点数取出:
还原E=129-127=2
还原M:1.01100000000000000000000=1.011
R=(-1)^S*M*2^E=(-1)^0*1.011*2^2=101.1=5.5
总结
综上为学习期间对大、小端存储和浮点数存储的个人理解,希望对你学习中遇到问题有所帮助,其中或许有理解不到位的地方,恳请指出,共同进步。