目录
1.补码存在的意义
因为cpu中没有减法器,不能进行减法,直接用二进制进行运算会出现错误。因此计算机中有独特的数据存储方式,称之为补码。补码存储在内存中,通过补码进行运算可以避免符号位对运算结果的影响。要得到补码,就要先得到数的二进制表示方式。这个数称为源码。正数的源码,补码,反码均相同,负数则需要进行转化。
通过符号位不变,其他位按位取反的方式可以把负数由源码变为反码,再对反码加一得到补码。相反,对补码取反加一也能得到原码。通过相同方式的转化,原码和补码可以互相转换。如:int a=-10;转换为原码为10000110,反码11111001,补码11111010。再通过相同的转换,可以得到10000101,10000110,成功转换了回来。正向和逆向都用相同的运算,让计算机的运算模块占用更少。
2.数据大小的处理
可以看到,在对char类型的变量赋值时,128的数据类型是int
计算机是如何将大的数据存入char类型的呢?
这需要一个截断的过程(针对内存)。
在赋值的时候,赋值的数据类型通常为int,这些数据也可能会存入更大或更小的类型。
而且我们经常可能会遇到不同类型数据的运算。他们在内存中占用的字节数不同。ALU(cpu运算器)在被设计时,其操作对象——操作数的字节大小被要求至少是int的字节数。在这种情况会运用到截断或者整型提升,他们都是对补码进行操作。
(1)截断
128转换为补码是00000000 00000000 00000000 10000000
char类型只能容纳最后一个字节(10000000),前面的部分会被截断。
此时变量a在内存中的数据就是10000000
(2)整型提升
在整型之间运算时,占用字节数较小的数据会在前边补充更多的位数,来进行运算。
因为运算器的操作对象字节大小至少为int,小于4个字节的数据会被转化为四个字节。
而如果4字节和8字节进行运算则会将4字节数据转换为8字节
转化的规则分为两种情况。
有符号数则是在前边补充符号位
无符号数直接在数的前面补充0
比如char a1 = -1
内存中补码为11111111
整型提升补充符号位后就是
11111111 11111111 11111111 11111111
char a2 = 1
内存中补码为00000001
整型提升补充符号位后就是
00000000 00000000 00000000 00000001
3.同样数据的不同使用
内存中同样的数据,使用方式不同,便会产生很多变化。
比如,我们用%u打印char类型的128,打印出的是一个很大的数
前面说过,a在内存中存储的是(10000000)
%u是打印无符号整型,需要先进行整型提升,补充符号位。
变成11111111111111111111111110000000
无符号数固定为正数,补码和原码相同,就直接把这个数打印出来。
用程序员计算器可以看到,它们是相同的。
这个原理,用浮点数也可以表明。
下一篇博客会用浮点数的存储,更加详细讲解数据的存储和使用方式。