整数在内存中的存储
整数在内存中使用反码进行存储。正数的原码反码补码相同。负数的反码是符号位不变,其他位对原码按位取反后,再加上1.
使用反码存储,是因为计算机可以把符号位和数值位进行统一处理,加法和减法也可以统一处理,补码和原码之间的换算也是相同的,不需要额外的硬件电路,非常方便。
大小端字节序
超过一个字节的数据在内存中存储就有存储顺序的问题。
大端(存储)模式:数据的低位字节内容保存在高位的地址,数据的高位字节内容保存在低位的地址。
小端(存储)模式:数据的低位字节内容保存在低位的地址,数据的高位字节内容保存在高位的地址。
举个栗子,一个整数,原码是 0x11223344,按照16进制进行存储。11所在的字节就是高位字节,44所在的字节就是低位字节。
在内存中一个整型要占用四个字节。它可能是 11 22 33 44的顺序存储,地址从左到右,由低到高,11是高位,却存在低位地址,所以说明该模式是大端存储。 也可能是 44 33 22 11的顺序存储,地址从左到右,由低到高,44是低位,存在低位地址,说明该模式是小端存储。
可以写个代码测试一下内存的存储模式。
int main()
{
int a = 1.
char *p = (char*)&a;
if(*p = 1)
{
printf("小端\n");
}
else
{
printf("大端\n");
}
return 0;
}
把取出的整型地址强制转换成char*的地址后,留下的就是低地址的一个字节。如果留下的是00,这显然是高位的数,低地址存高位内容,就是大端。留下的是01,也就是1,这是低位的数,存在低地址,所以是小端。
char型数据,只能存(-128 - 127)的数,因为只能存1个字节,就是8个比特位的数,就算把数塞满,最多也就是127,如果符号位是1的话,那就是负数。如果是无符号的char----unsigned char,可以存(0 - 255)的数。
浮点数的存储
根据国际标准IEEE754,任意一个二进制数V = (-1)^s *M*2^E. 这里的(-1)^s表示 -1的s次方,2^E表示2的E次方。
(-1)的s次方表示符号位。s是0就是整数,是1就是负数。
M是大于等于1小于2的有效数字。
2的E次方是指数位。
对于32位的浮点数,最高的1位存S,后面的8位存E,再后面的23位存M
对于64位的浮点数,最高的1位存S,后面的11位存E,再后面的52位存M
先把浮点数写成二进制数,然后按照二进制数浮点数存储的方式计算就知道浮点数在内存中如何存放了。
计算机保存M时,比如M=1.01,只保存后面的01,等到读取时再把前面的1加上去。这样就能多保存一位数字更精确了。
E全为0时代表这个数是接近于0的很小的数,E全为1时代表这个数是接近于无穷大的很大的数字。
E不全为0或者1时,取出时要-127,才能得到真实值。