一、基础概念
1.1 理论
- 正数的原码、反码、补码都一样
- 负数的补码=反码+1;反码=原码取反
- 计算机中,数值一律用补码来表示和存储。因为补码解决了正负数符号的问题,同时方便加减法运算
- 补码中最高位为符号位,其余为数据位
- 不同数据类型的长度不同,这样设计的原因是为了节省资源,避免造成不必要的浪费
- 符号位参与数据位加减运算,若符号位溢出,则舍弃。比如符号位为1,加1后变成10,此时舍去溢出的1
1.2 案例
- Java中byte类型,长度1字节8位
- 8位长度的数据类型,1位符号位、7位数据位。由此该类型的取值范围:-128~127
- 二进制补码为:1000 0000 ~ 0111 1111
- -128不能用原码或反码表示,因为8位长度的原码和反码取值范围为-127到+127
- 为了在数的表示上消除编码映射的不唯一性,人为规定-128的补码为1000 0000
- 0也比较特殊,其原码、反码、补码如下表。无论正数、负数,0的补码都是0000 0000
数值 | 原码 | 反码 | 补码 |
---|---|---|---|
0-正数 | 0000 0000 | 0000 0000 | 0000 0000 |
0-负数 | 0000 0000 | 1111 1111 | 0000 0000 |
二、案例实践
2.1 补码计算
题目:分别计算7和-7的反码、补码?注:数据长度为1字节8位
7的补码计算过程
a、7为正数,所以补码=反码=原码
b、7为十进制数,将其转换为二进制,即为原码
原码:7 --> 0000 0111
反码:0000 0111
补码:0000 0111
-7的补码计算过程
a、-7位负数,所以补码=反码+1=原码取反+1
b、原码没有正负数之说,都按正数计算,所以-7的原码依然按7计算。
c、7为十进制数,将其转换为二进制,即为原码
原码:7 --> 0000 0111
d、将原码取反后,即为反码
反码:0000 0111 --> 1111 1000
e、将反码加1,即为补码,也就是计算机存储的值
补码:1111 1000 ---> 1111 1001
结论:若已知补码,首先可判断其正负数,其次根据上面推导过程倒推,即可得出十进制的原数值
2.2 按位取反
背景:在java或数据库中,有一种运算符“~”,该运算符的意义就是按位取反。即字面意思:数值的每一位都取反,包含符号位,其实质就是:0–>1,1–>0
问题:~7的结果是多少?-7的结果是多少?
7的计算过程
a、7的补码:0000 0111
b、按位取反:1111 1000
c、补码为1111 1000的原数值为-8(具体推导参考上一节内容)
-7的计算过程
a、-7的补码:1111 1001
b、按位取反:0000 0110
c、补码为0000 0110的原数值为6(具体推导参考上一节内容)
java程序
结论:~x = -x-1
2.3 加减运算
问题:计算7+3和7-3,并说明其过程?
7+3
a、7的补码:0000 0111;3的补码:0000 0011
b、补码相加,逢二进一,符号位溢出舍弃
7 0000 0111
3 0000 0011
------------------
0000 1010
c、补码为:0000 1010 的原数值是10
7-3
a、7-3等式转换为-3+7
b、-3的补码:
原码 反码 补码
0000 0011-->1111 1100 ---> 1111 1101
c、补码相加,逢二进一,符号位溢出舍弃
7 0000 0111
-3 1111 1101
------------------
舍弃 10000 0100
------------------
0000 0100
d、补码为0000 0100的原数值是4
三、参考工具
3.1 计算器
使用windows10自带的计算器,打开方式:win+r,输入calc
长度类型:
- 字节(BYTE):1字节=8位
- 字(WORD):1个字=2字节=16位
- 双字(DWORD):2个字=4字节=32位
- 四字(QWORD):四个字=8字节=64位
进制:
- HEX:十六进制
- DEC:十进制
- OCT:八进制
- BIN:二进制