整数表达方式
原码
原码就是整型的二进制表达。用二进制表示整数也有正负的需要,因此用最高位来表示正负,0为正,1为负。如果都是正数或负数相加不会出现错误,但如果是一正一负相加就会出错了。
1 -> 0000,0001
-1 -> 1000,0001
1+-1 -> 1000,0010 B = -2 D
这个例子可以发现,
当然我们会想,如果直接用原码进行减法计算不就好了?直观的看,当首位表示正负时,符号位不应该参与运算,而是要通过符号位来判定是进行加法还是减法运算。计算机中是没有减法器的,减法器将大大增加芯片设计的复杂度以及成本。同时还要增加电路来识别判断符号位。这会变得很麻烦。
因此思路是如何将减法转换为加法,同时符号位也要直接参与运算。乘法和除法也是可以通过乘法来实现的,因此所有的计算最终都可以通过加法来实现。
反码 1’s Complement
为了解决正负数相加出错的问题,我们可以想到将减数或被减数进行取反操作,因此出现了反码。
1 -> 0000,0001
-1 -> 1000,0001 -> 1111,1110
1+-1 -> 1111,1111 -> 1000,0000 = -0
反码看似解决了整个问题,但又出现了新问题,那就是有了两个零,+0和-0。
实际上反码的唯一作用就是作为求补码的中间步骤。
正数的反码还是原码。
负数的反码为符号位保留,数值位取反。
补码 2’s Complement
为什么会有补码呢?以时钟为例,12小时制的时钟实际上是以12为模的
2 mod 12 = 2
-10 mod 12 = 12-10 =2
14 mod 12 = 2
也就是说当我们想把时钟从6点跳到4点时,可以将时针逆时针回拨2小时,即6-2=4;或者将时钟顺时钟拨10小时,即16%12 =4 。因此a减去b就相当于a加上b的补数,即a-b=a+a补
同余的概念
两个整数a,b若他们除以整数m所得的余数相等,则称a,b对于模m同余。从中我们就可以将减法转换为加法。
一个数的反码+1,实际上是这个数对于它的模的补数,而这个模就是n位二进制所能表示的最大十进制数。
以8为二进制数为例,当超过1111,1111时高位被舍弃,相当于CPU自动对所有二进制数做了2^8取模计算。因此就可以得到补码的计算方式。
补码的计算
- 正数的补码还是原码
- 负数的补码为真值取反码后+1
- 补码逆求码有两种方法
- 补码-1后取反
- 补码取反+1
移码
整型排放方法
- 大端
- 小端
为什么又大小端存储
大端小端其实不一定有什么好处,知识早期计算机体系设计者的设计方法不同。在实际中两种方式都有在用,特别是TCP/IP数据链路层中对文件的加工传输,编译器中放入内存。