1.整形在内存中的存储
1.1原码、补码及反码
在计算机系统中,数值一律用补码的形式表示和存储
整数有三种二进制的表示方法,即原码、反码和补码。
正数的原码、补码及反码均相同
负数的补码=反码+1得到,而反码则是原码在符号位不变的基础上,数值位按位取反得到,其中最高位表示符号位。
当知道补码时,通过按位取反再加一或者减一再按位取反得到原码
1.2大小端字节序存储
大端字节序存储:将数据的低位字节处的数据存放在内存的高地址处,高位字节处的数据存放在内存的低地址处。
小端字节序存储:将数据的低位字节处的数据存放在内存的低地址处,高位字节处的数据存放在内存的高地址处。
如何判断大小端字节序存储?
#include<stdio.h>
int main()
{
int a = 0x11223344;
//通过第一个字节中的数据判断大小端
char* p = (char*)&a;//&a的类型为int*
//通过强制转换成char*类型赋给指针p,从而实现访问一个字节
//如果是小端字节序存储,则十六进制下第一个字节的数据为44,十进制位则为68
if (*p == 68)
printf("小端字节序存储");
else
printf("大端字节序存储");
return 0;
}
1.3常见的数据转换练习
2.浮点数在内存中的存储
2.1浮点数存储规则
根据标准规定:任意一个二进制浮点数V可以表示成::(-1)^S*M*2^E
其中S用来表示浮点数的正负,S为0则为正,S为1则为负
M表示有效数字,1<=M<2
E代表指数位
例如:十进制的5.5,写成二进制则为101.1;则可表示为(-1)^0*1.011*2^2
对于32位的浮点数:最高位为符号位S,接着8位为指数E,剩余的23位为有效数字M
对于64位的浮点数:最高位为符号位S,接着11位为指数E,剩余的52位为有效数字M
其中:
M存取
M为1.xxxxx,因为第一位总是为1,因此可以省去,而只存小数位, 例如1.011则只存011;而在取出时,则在M前加上第一位的1
E存入
E为无符号整数,如果E为8位,则取值范围为0~255;为11位则取值范围为0~2047;但是某些小数按照科学计数法计算时,可能E会出现负数,例如10进制的0.5,二进制则为0.1,表示形式为(-1)^0*1.0*2^(-1);这时E为-1。
于是规定在存入内存中时,E的真实值必须先加上一个中间值在进行存储,8位则是127;11位则是1023
E取出
E不为全0或1:将指数E的计算值减去中间值(128或者1023)得到真实值;
E为全0或1:全为0时,指数E=0-127或-1023;2^E已经为一个非常小的数字,接近0;因此有效数字M则不再加上第一位的1,而是还原为0.xxxxxx的小数,
全为1时:如果有效数字全为0,则表示无穷大,正负取决于S
2.2练习
#include<stdio.h>
int main()
{
int n = 10;
float* p = (float*)&n;
printf("n=%d\n", n);
printf("*p=%f\n", *p);
*p = 10.0;
printf("n=%d\n", n);
printf("*p=%f\n", *p);
return 0;
}