符号数表示
原码:最高位为符号,其余二进制真值
补码:最高位符号
- 正:与原码相同
- 负:符号位不变,其余取反后再加1
-69
原码:1100 0101
补码:1011 1011
8位原码的表示范围:-127 ~ 127
8位补码的表示范围:-128 ~ 127
因为补码利用了-0
这个编码,作为最小的负数
比如8位有符号数,最小数-128
的编码就是1000 0000
最大数127
的编码是0111 1111
(正数的补码和原码一样)
所以补码可表示范围比原码多1
n位数:$-2^{n-1} \sim 2^{n-1}-1$
tips:
因为计算机中以补码形式存储数据,所以32
位的有符号数的int
的范围是:$-2^{31} \sim 2^{31}-1$,即 -2147483648 ~ 2147483647
16
位的有符号数的short
的范围是:$-2^{15} \sim 2^{15}-1$,即 -32768 ~ 32767
- 已知
x
的补码,求-x
的补码:符号位、数值位全部取反,再+1
-69
补码:1011 1011
取反+1:0100 0101 即69的补码
int main() {
int a = 2147483647;
cout << a+1 << endl;
return 0;
}
-2147483648
反码
- 正数:与补码相同
- 负数:原码符号不变,其余取反
移码:补码符号位取反,移码只能用于表示整数
真值增大时,移码也是增大的
总结
补码的作用
用加法运算替换减法运算
88-66
找到-66的补码:
模$2^{8}$ - 66的绝对值(补码最原始的计算方式)= 1 0000 0000 - 0100 0100 = 1011 1110
然后用 88 = 0101 1000
,所以
0101 1000
+ 1011 1110
= 10001 0110
转化成十进制就是22
算数移位
补码
以最低位的1为分界
右移:前段跟反码一样,所以补1
左移:后段跟原码一样,所以补0
逻辑移位
逻辑移位可以看作是对无符号数的算数移位,符号位也会移动,最高位补0
原码、补码一位乘法
原码:
- 符号位通过异或确定,数值位由被乘数和乘数的绝对值进行n轮加法、移位
- 每次加法可能是
+0
、+x的原码
,看MQ
的最低位(0 1)
- 每次移位是逻辑右移
补码:
- 符号位、数值位都是由被乘数和乘数进行n轮加法、移位,最后还有一次加法
- 每次加法可能是
+0
、+x的补码
、+(-x)的的补码
,看辅助位和MQ'最低位'
的差值(0 1 -1)
- 每次移位是补码的算数右移,整数补0,负数补1