0x00 有符号数 - 负数
最高位为1,代表负数
除去最高位剩余位以无符号数解析,符号为负 -> 原码
计算机以补码保存有符号数
0x01 原码
最高位为符号位,其余位为数值
0 001 0011 -> 0x13 -> 19
1 001 0011 -> -0x13 -> -19
0x02 反码
正数的反码是原码
负数反码 -> 最高位不变,其余取反
1 001 0011
1 110 1100 -> 反码
----------
0xEC
0x03 补码
正数的补码是原码
负数补码 -> 负数反码+1
1 110 1100 -> 反码
1 110 1101 -> 补码
----------
0xED
-19 -> 原码 0x13 -> 反码 0xEC -> 补码 0xED
以上补码反码以8bit为例
0x04 总结
原码、反码、补码针对有符号数,且针对的是负数
正数的反码、补码都是其原码本身
原码是人类理解的有符号数形式
反码是原码转为补码的中间码
补码是有符号数最终存储在计算机内的形式
个人理解:
以8位寄存器为例
0xFF + 1 = 0 -> 0 - 1 = 0xFF (借位)
看成有符号数则 0xFF 对应 -1 ,因为我们的认知中 -1 + 1 = 0, 0 - 1 = -1
0xED + 19 = 0 -> 0 - 19 = 0XED (借位)
看成有符号数则 0xED 对应 -19
以16位寄存器为例
0xFFFF + 1 = 0 -> 0 - 1 = 0xFFFF (借位)
看成有符号数则 0xFFFF 对应 -1
以32位寄存器为例
0xFFFFFFFF + 1 = 0 -> 0 - 1 = 0xFFFFFFFF (借位)
看成有符号数则 0xFFFFFFFF 对应 -1
通过以上规律计算-5
8位 -5 = 0 - 5 = 0xFB
16位 -5 = 0 - 5 = 0xFFFB
32位 -5 = 0 - 5 = 0xFFFFFFFB
负数即小于0的数,向0后面数数,根据以上规则可知0向后数1则变为了1111 1111 ...,最高位0 1则为边界
计算机对于负数的理解就是我们所说的补码.原码只是为了方便我们人类阅读
0xFB -> 1111 1011 -> 1111 1010 -> 1 000 0101 -> -5 补码转原码
加减法也就是从这个数开始向前或向后数数.所以减去一个数,也可以看成负数加上几个数,因为是相对的
1 - 2 = -2 + 1 = FE(0向后数2个数) + 1 = FF(FE向前数一个数) = -1
出现这种情况的原因是受到了数据宽度的制约,其实是硬件约束
最高位0 1为正负数边界,计算机本身就以补码来存储负数,原码只是为了方便人类阅读
计算机以指定的数据宽度存储0、1, 如何看待存储的0、1由使用者来定义.可以将其看为有符号/无符号数、文本文件、音频文件等等
计算机不识别正负数,由于受到数据宽度的制约,比0小的数则从FFFF(16位)开始,这样可以看成FFFF表示-1,但人类看起来不是很直观,于是原码、反码、补码便出现,将补码转为原码便于人类理解
有不对的地方,请各位大佬指点