“大小端字节序”以及“整型和浮点型在内存中的存储”。
目录
前言:
数据在内存中是如何存储的呢?
本文主要介绍“大小端字节序”以及“整型和浮点型在内存中的存储”。
一、大小端字节序
计算机系统以字节为单位,每个地址单元都对应一个字节,一个字节为8bit。但在C语言中char占8bit,short占16bit等,这就导致如何将多个字节安排的问题。
大端存储模式:指数据的低位保存在内存的高地址中,而数据的高位保存在内存的低地址中
小端存储模式:指数据的低位保存在内存的低地址中,而数据的高位保存在内存的高地址中
例如:int a=-10;
原码:10000000 00000000 00000000 00001010
反码:11111111 11111111 11111111 11110101
补码:11111111 11111111 11111111 11110110
十六进制:(高位)FF FF FF F6(低位)
大端存储模式:(低地址)FF FF FF F6(高地址)
小端存储模式:(低地址)F6 FF FF FF(高地址)
通过程序实现大小端的判断
#include<cstdio>
int main()
{
int a=1; //补码:01111111 11111111 11111111 11111111
char* p = (char*)&a; // char *p访问一个字节
if (*p == 1)
printf("小端\n");
else
printf("大端\n");
return 0;
}
二、整型和浮点型在内存中的存储
一个变量的创建是要在内存中开辟空间的,空间的大小是根据不同的类型而决定的。
1.整型在内存中的存储
计算机中的整数有三种表示方法:原码、反码、补码。均由符号位和数值位两部分组成。
符号位:0表示“正”,1表示“负”
数值位:正整数和0的原码、反码、补码均相同,而负整数原码、反码、补码各不相同:
原码:直接二进制表示
反码:符号位不变,数值位按位取反(0变1,1变0)
补码:在反码的基础上+1
对于整型来说,数据以 补码 的形式在内存中存放。
例如:1+(-1)
源码计算:00000000 00000000 00000000 00000001+10000000 00000000 00000000 00000001=
10000000 00000000 00000000 00000010 转化为十进制为-2出现问题
补码计算:
1的原码、反码、补码:00000000 00000000 00000000 00000001
-1的原码:10000000 00000000 00000000 00000001
-1的反码:11111111 11111111 11111111 11111110
-1的补码:11111111 11111111 11111111 11111111
1的补码+(-1的补码):00000000 00000000 00000000 00000001+11111111 11111111 11111111 11111111
=(舍去超过32位的最高位1)1 00000000 00000000 00000000 00000000 转化为十进制为0
结果正确
2.浮点型在内存中的存储
根据国际标准IEEE 754规定,任意一个二进制浮点数V可以表示成下面的形式:
(-1)^S*M*2^E
(-1)^S表示符号位,当S为0时,V为正数,当S为1时,V为负数(与整数的符号位相同)
M表示有效位,1<=M<2(类比十进制科学计数法)
2^E表示指数位
举例:
十进制的5.0转化为二进制为101.0=(-1)^0*1.01*2^2
则S=0,M=1.01,E=2
IEEE 754规定:
对于32位的浮点数,最高位1位S,接着的8位是指数E,剩下的23位位有效数字M。
S E E E E E E E E M M M 对于64位的浮点数,最高位1位S,接着的11位是指数E,剩下的52位位有效数字M。
易知,M的整数位必为1,在计算机内部保存时被舍去,只保存小数部分,读取的时候,再把第一位的1加上去。这样,节省了1位有效数字。对于32位的浮点数就可以保存24位的有效数字M。
指数E比较复杂
首先,E为一个无符号整数(unsigned int)
当E为8位,取值范围位0-255,当E为11位时,取值范围为0-2047。但是科学计数法中的E可以为负数。所以IEEE 754规定,存入内存时E的真实值必须再加上一个中间数,对于8位的E,中间数为127,对于11位的E这个中间数为1023。(保证E为非负数)
例如:2^10中,E为10保存成32位浮点数时,必须保存为10+127=137,即1000 1001(补码)
E从内存中取出还可以分为三种情况
1、E不全为0或不全为1
此时,需要先得到真实值,即减去127或1023,再将有效数字M前加上第一位的1。
2、E全为0
此时,指数E为1-127=-126或1-1023=-1022(规定),2^E接近于0,此时有效数字M不再加上第一位的1,而是还原为0.xxxxx的小数,这样做是为了表示正负0,以及接近于0的数字。
3、E全为1
此时,如果有效数字M全为0,表示正负无穷大(正负取决于符号位S)。
例如:1、(32位浮点数为例)十进制的0.5转化为二进制为0.1=(-1)^0*1.0*2^(-1) E=-1, -1+127=126 126转化为二进制0111 1110,M=1.0去掉整数部分,最终表示为:
0 01111110 00000000000000000000000
总结
以上就是关于“大小端字节序”以及“整型和浮点型在内存中的存储”的内容。
PS:感谢鹏哥