一:原码,反码,补码定义
1.原码: 就是符号位加上真值的绝对值, 即用第一位表示符号, 其余位表示值。
2.反码: 正数的反码是其本身;负数的反码是在其原码的基础上, 符号位不变,其余各个位取反。
3.补码: 正数的补码就是其本身;负数的补码是在其原码的基础上, 符号位不变, 其余各位取反, 最后+1。 (即在反码的基础上+1)
二:负数时,原码,补码互转公式
(-x)补码 = 2^n-x//原码转补码
值 = -最高位值+剩余位数总和//补码转原码
-127的原码是1111 1111 反码是 1000 0000 补码是 1000 0001,补码=129
使用补码公式计算是 2^8-127=129
补码是1000 0001,使用转原码公式计算是 -12^7 + 12^0 = -128+1=-127
特殊的补码 1000 0000 使用转原码公式计算是 -1*2^7 + 0 = -128
三:超出范围转化时的情况
unsigned char bbb = 0x80; //128 补码是 1000 0000
signed char ccc = (signed char)bbb; //转变为负数,适用于负数转原码公式 -1*2^7 + 0 = -128
printf("ccc的值是: %d\n", ccc); // 输出-128
java语言也有类似的情况
四:补码运算优势
原码有负0和正0 即:-0和+0
| 原码 | 反码 | 补码 | 说明 |
|---|---|---|---|
| 1000 0000 表示-0 | 1111 1111 | 0000 0000 | 补码是1 0000 0000 溢出1位去掉是 0000 0000 |
| 0000 0000 表示+0 | 0000 0000 | 0000 0000 | 正数原码反码补码相同 |
为什么计算机使用补码做计算?
1:补码 负0和正0 是统一的
2:只有补码,符号参与了运算,结果是正确的
3:补码计算,可以只有加法 5-3转化为5+(-3) 补码运算可以算正确