一、整形在内存的存储
整形的内存存储的是该数二进制的补码,正数的补码则是原码,负数的补码则需要对原码通过取反,再+1得到负数的补码。
正数的原码、反码和补码相同。
十六进制在内存中是倒放。
例如:20的十六进制:0X 00 00 00 14
14 00 00 00
数据存放中其实存放的都是补码,计算是需要将原码转换成补码。
负数的补码转换成原码有2种方法:
//-1,取反 //取反,+1
6.大端存储(大端字节序存储)
定义:把一个数据的低位字节的内容存放在高地址处,高位字节的内容存放在低地址中。
7.小端字节(小端字节序存储)
定义:把一个数据的地位字节的内容存放在低地址处,高位字节的内容存放在高地址中。
例如:int a=1 的十六进制为0x 00 00 00 01
小端 | 01 | 00 | 00 | 00 |
大端 | 00 | 00 | 00 | 01 |
低 | 高 |
针对数据存储中的运算,需要按照补码形式进行运算
%d是打印有符号数,会认定高位数的正负
%u是打印无符号数,不会认定高位数的正负
char—>-128~127,运算过程中不可能超过此范围
unsigned char—>0~255,运算过程中不可能超过此范围
练习:整形在内存的存储相关计算
例1:
int main()
{
char a=-1;
signed char b=-1;
unsigned char c=-1;
printf("a=%d b=%d c=%d",a,b,c);
return 0;
}
对char a=-1进行分析
a的原码:10000000000000000000000000000001
a的反码:11111111111111111111111111111110
a的补码:11111111111111111111111111111111
-1是整数,32个bit位,转换成char类型,占8个bit位
对a的补码进行截断:11111111
再进行整形提升,因为是有符号整形,所以在高位前补1
则a的补码为11111111111111111111111111111111
又因为打印时为%d类型,%d是有符号数
所以结果为-1
因为char=signed char,所以分析同上述
对unsigned char c=-1进行分析
c的原码:10000000000000000000000000000001
c的反码:11111111111111111111111111111110
c的补码:11111111111111111111111111111111
对c的补码进行截断:11111111
再进行整形提升,因为是无符号整形unsigned,所以在高位前补0
则c的补码为00000000000000000000000011111111
结果为255
例2:
int main()
{
char a=-128;
printf("%u\n",a);
return 0;
}
对char a=-128进行分析:
a的原码:10000000000000000000000010000000
a的反码:11111111111111111111111101111111
a的补码:11111111111111111111111111111111
-128是整数,32个bit位,转换成char类型,占8个bit位
对a的补码进行截断:11111111
再进行整形提升,因为是有符号整形,所以在高位前补1
则a的补码为11111111111111111111111111111111
又因为打印时为%u类型,%u是无符号数,当进行%进行打印时,会认定内存存储的是无符号数,没有符号为可言,所有数字都是有效位。
结果为429496718
例3:
int main()
{
unsigned int i;
for(i=9;i>=0;i--)
{
printf("%u\n",i);
}
return 0;
}
当i减到-1时
用补码进行运算i=-1
10000000000000000000000000000001 -原码
11111111111111111111111111111110 -反码
11111111111111111111111111111111 -补码
因为是%u打印,则没有符号位可言,所有数字都是有效数,则i又会以i的补码重新进入for循环
所以该程序是死循环
二、浮点数存储的规则
整数的形式不能用浮点数形式打印,反之同理。
任意一个二进制浮点数V可以表示成下面的形式
(-1)^s * M * 2^e
(-1)^s表示符号位,当s=0时,V为正数;当s=1时,V为负数
M表示有效数字,大于等于1,小于2
2^e表示指数位
例1:
V=5.5
=101.1
=1.011*2^2
运用科学计数法,将小数点向左移动两位,但是因为本身是二进制,所以为2^2
=(-1)^0*1.011*2^2
s=0,M=1.011,E=2
例2:
32bit 位
float f=9.0
=>二进制为1001.0
=>(-1)*1.001*2^3
s=0,M=1.001,E=3
s=0表示该数的正负
M=1.001将小数点后的数写下,若不够32bit位,则往后面添0,直到到达32bit位
00100000000000000000000
E=3,127+3=130,130的二进制位10000010
所以float f=9.0的二进制位0 100000010 00100000000000000000000
转换成十六进制,以4个bit 位为组
0x 41 10 00 00
ok,内容大致就这些,希望我的笔记能对你有帮助,如果内容又错误,也非常高兴佬们能够指出,那么,有缘再见