整型内存存储的数据形式
计算机中的有符号数(整形,**即首位为符号位,0表示”正”,1表示”负”**)有三种表示方式,即原码,反码和补码。(无符号数的原码反码补码和符号位为正时规则相同。)
当符号位为正时(首位为0)
则原码反码补码相同。
当符号位为负时(首位为1)
原码
将值翻译成二进制形式。
反码
原码的符号位不变,其他位依次取反。
补码
在反码的基础上+1就可以得到补码。
int a = 4; //4个字节-32bit
//转换成二进制
//原码:00000000 00000000 00000000 00000100
//反码:00000000 00000000 00000000 00000100
//补码:00000000 00000000 00000000 00000100
int a = -5;
//转换成二进制
//原码:10000000 00000000 00000000 00000101
//反码:11111111 11111111 11111111 11111010
//补码:11111111 11111111 11111111 11111100
对于整形来说:内存中存放的时补码(补码可以让加减法统一处理,无需额外的硬件电路)。
大小端的概念
大端(存储)模式,指数据的低位保存在内存的高地址中,而数据的高位,保存在内存的低地址中;
小端(存储)模式,指数据的低位保存在内存的低地址中,而数据的高位,保存在内存的高地址中;
大端: 假设有十六进制数 0x11223344
, 内存从低位到高位存储0x11223344
。
小端: 假设有十六进制数 0x11223344
, 内存从低位到高位存储0x44332211
。
整形提升
//当将char类型打印整形时会进行整形提升,根据符号位来补充剩下的位以保证有32位
//符号位为1则全补1
//符号位为0则全补0
char a = -1;
unsigned char b = -1;
printf("a=%d,b=%d",a,b); // a=-1 b=255
//a的补码:11111111
//整形提升后补码:11111111 11111111 11111111 11111111,则原码化为十进制为-1
//b的补码:11111111
//因为没有符号位所以默认补充0,则整形提升后补码:0000000 00000000 00000000 11111111,则原码化为十进制为255
有符号数和无符号数区别
有符号数
当声明int
或char
等类型默认为有符号数,即bit的第一位为符号位(0正1负)。
无符号数
声明变量前使用关键字unsigned
即为无符号数,即bit的第一位为有效位,不做符号位。
char a = 0b10000001;//有符号数 char为8bit
unsigned char b = 0b10000001;//无符号数
printf("%d\n",a);//-127
printf("%d\n",b);//129
浮点型在内存的存储形式
任何二进制浮点数V可以根据IEEE754表示成以下形式:
$$
(-1)^SM2^E
$$
(-1)^S表示符号位,当S=0,V为正数,当S=1,V为负数。
M表示有效数字(即化成的进制数),大于等于1,小于2.
2^E表示指数位。
9.0
化二进制为1001.0
用以上准则表示为(-1)^0 * 1.001 * 2^3
,得出:
$$
S=0 \quad M=1.001 \quad E=3
$$
浮点型存入内存方式
IEEE 754规定:对于32位的浮点数,最高的1位是符号位s,接着8位是指数E(E为无符号数),剩下的23位位有效数字M。(为防止E出现负数,32位默认**+127后再进行存储,为了增加精度,存M时默认去掉小数点前的1**。)
即上方存储到内存中为0 10000010 00100000000000000000000
。
对于64位浮点数则最高的1位是符号位s,接着11位是指数E,剩下的52位位有效数字M。(规则与32位相同,64位默认**+1023**后再进行存储)