原码是机器数中最简单的一种表示形式,符号位数为
0
0
0 表示正数,符号位
1
1
1 表示负数,
0
0
0 表示正数,符号位是在计算机中用一个数的最高位来存放符号,而真值是带有
+
+
+ 或者是
−
-
− 符号的数,由于计算机分不清正负符号,所以需要转换成原码
下面这是一个八比特寄存器
2 7 2^7 27 | 2 6 2^6 26 | 2 5 2^5 25 | 2 4 2^4 24 | 2 3 2^3 23 | 2 2 2^2 22 | 2 1 2^1 21 | 2 0 2^0 20 |
---|
最高位 2 7 2^7 27表示符号位正与负
- 例如:十进制正数 14 14 14转换成二级制为 1110 1110 1110,由于是在八位寄存器中所以应该为
2 7 2^7 27 | 2 6 2^6 26 | 2 5 2^5 25 | 2 4 2^4 24 | 2 3 2^3 23 | 2 2 2^2 22 | 2 1 2^1 21 | 2 0 2^0 20 |
---|---|---|---|---|---|---|---|
0 0 0 | 0 0 0 | 0 0 0 | 0 0 0 | 1 1 1 | 1 1 1 | 1 1 1 | 0 0 0 |
最高位表示符号
用逗号将符号位和数值位分隔开,当
x
=
−
1100
x=-1100
x=−1100时,
[
x
]
原
=
2
4
−
(
−
1110
)
=
1
,
1110
[x]_{原} =2^4-(-1110)=1,1110
[x]原=24−(−1110)=1,1110
上面的是整数,下面是小数原码:
[
x
]
原
=
{
x
1
>
x
≥
0
1
−
x
0
≥
x
>
−
1
[x]_{原}= \begin{cases} x& \text{} 1>x\ge0 \\ 1-x& \text{} 0\ge x>-1\end{cases}
[x]原={x1−x1>x≥00≥x>−1
x
x
x为真值
- 例如
当 x = 0.1101 x=0.1101 x=0.1101时, [ x ] 原 = 0.1101 [x]_{原}=0.1101 [x]原=0.1101, x = − 0.1101 x=-0.1101 x=−0.1101时, [ x ] 原 = 1 − ( − 0.1101 ) = 1.1101 [x]_{原}=1-(-0.1101)=1.1101 [x]原=1−(−0.1101)=1.1101
当然既然能能根据真值求原码,反过来原码也可以求真值
- 例如
当 [ x ] 原 = 1.0011 [x]_{原}=1.0011 [x]原=1.0011时, x = 1 − [ x ] 原 = 1 − 1.0011 = − 0.0011 x=1-[x]_{原}=1-1.0011=-0.0011 x=1−[x]原=1−1.0011=−0.0011
注意:当
x
=
0
x=0
x=0时,有两种形式来表示
[
+
0.0000
]
原
=
0.0000
[+0.0000]_{原}=0.0000
[+0.0000]原=0.0000,
[
−
0.0000
]
原
=
1
−
(
0.0000
)
=
1.0000
[-0.0000]_{原}=1-(0.0000)=1.0000
[−0.0000]原=1−(0.0000)=1.0000
所以
[
+
0
]
原
[+0]_{原}
[+0]原不等于
[
−
0
]
原
[-0]_{原}
[−0]原
正数:
原码
→
不变
反码
→
不变
补码
原码\xrightarrow[]{不变}反码\xrightarrow[]{不变}补码
原码不变反码不变补码
并且这个从补码到原码也是一样都是不变的
负数:
原码
→
数值取反
符号位不变
反码
→
末尾
+
1
补码
原码\xrightarrow[数值取反]{符号位不变}反码\xrightarrow[]{末尾+1}补码
原码符号位不变数值取反反码末尾+1补码
补码转反码执行相反的运算——末尾
−
1
-1
−1
这里的数值取反意思是
0
0
0变成
1
1
1,
1
1
1变成
0
0
0(除了符号位不变)
- 例如:
+ 17 +17 +17 (八比特位)原码、反码、补码都为 0 , 0010001 0,0010001 0,0010001
− 17 -17 −17 (八比特位)原码为 1 , 0010001 1,0010001 1,0010001,反码为 1 , 1101110 1,1101110 1,1101110,补码 1 , 1101111 1,1101111 1,1101111
在这里补充一下无符号位减法运算
01100011
−
00001001
=
01100011-00001001=
01100011−00001001= 我们手算的时候可以进行数不够可以进行借位
但是在计算机中实现减法中成本较高,所以可以将计算方法变化一下,将其变成加法计算器能完成的
首先,将被减数不变,减数全按位取反,再末位
+
1
+1
+1,减法变加法,将
00001001
00001001
00001001转成
11110111
11110111
11110111,最后与被减数相加得
01100011
+
11110111
=
101011010
01100011+11110111=101011010
01100011+11110111=101011010 但是我在这里限制的是八比特寄存器 多出来了一位 最后为
01011010
01011010
01011010
这里有一个补码与原码之间快速切换的技巧(两者可以相互转换)
原码
→
这个左边所有的数值位取反
从右往左找到第一个
1
补码
原码\xrightarrow[这个左边所有的数值位取反]{从右往左找到第一个1}补码
原码从右往左找到第一个1这个左边所有的数值位取反补码
- 例如:
− 12 -12 −12
原码为 10001100 10001100 10001100 这里我们为了更加容易好看,绘制了一个表格
1 1 1 | 0 0 0 | 0 0 0 | 0 0 0 | 1 1 1 | 1 1 1 | 0 0 0 | 0 0 0 |
---|---|---|---|---|---|---|---|
↑ \uparrow ↑ |
从右往左第一个 1 1 1 从这个 1 1 1开始也就是从箭头所示开始将所有的数值进行取反得到
原码 | 1 1 1 | 0 0 0 | 0 0 0 | 0 0 0 | 1 1 1 | 1 1 1 | 0 0 0 | 0 0 0 |
---|---|---|---|---|---|---|---|---|
补码 | 1 1 1 | 1 1 1 | 1 1 1 | 1 1 1 | 0 0 0 | 1 1 1 | 0 0 0 | 0 0 0 |
反码与补码也可以进行加减运算,方式与原码计算方法一样
[ A ] 补码 + [ B ] 补码 [A]_{补码}+[B]_{补码} [A]补码+[B]补码 | [ A ] 补码 − [ B ] 补码 [A]_{补码}-[B]_{补码} [A]补码−[B]补码 |
---|---|
[ A ] 反码 + [ B ] 反码 [A]_{反码}+[B]_{反码} [A]反码+[B]反码 | [ A ] 反码 − [ B ] 反码 [A]_{反码}-[B]_{反码} [A]反码−[B]反码 |
三种码可以能在一起混合计算,但是没有什么意义
- 这是我第一次写博客,请多多指教