二进制数
计算机中,数以二进制的方式存储。
二进制整数
二进制整数转换为十进制数
记
B=bjbj−1⋅⋅⋅b2b1b02
B
=
b
j
b
j
−
1
·
·
·
b
2
b
1
b
0
2
则其对应的十进制数为
N=bj×2j+bj−1×2j−1+⋅⋅⋅+b1×21+b0×20
N
=
b
j
×
2
j
+
b
j
−
1
×
2
j
−
1
+
·
·
·
+
b
1
×
2
1
+
b
0
×
2
0
十进制数转换为二进制数
记十进制数
N=akak−1⋅⋅⋅a2a1a0
N
=
a
k
a
k
−
1
·
·
·
a
2
a
1
a
0
设其对应的二进制表达为
N=bjbj−1⋅⋅⋅b2b1b02
N
=
b
j
b
j
−
1
·
·
·
b
2
b
1
b
0
2
即有
N=bj×2j+bj−1×2j−1+⋅⋅⋅+b1×21+b0×20
N
=
b
j
×
2
j
+
b
j
−
1
×
2
j
−
1
+
·
·
·
+
b
1
×
2
1
+
b
0
×
2
0
等式两边同除2得
N2=bj×2j−1+bj−1×2j−2+⋅⋅⋅+b1×20+b02
N
2
=
b
j
×
2
j
−
1
+
b
j
−
1
×
2
j
−
2
+
·
·
·
+
b
1
×
2
0
+
b
0
2
记
Q0=bj×2j−1+bj−1×2j−2+⋅⋅⋅+b1×20
Q
0
=
b
j
×
2
j
−
1
+
b
j
−
1
×
2
j
−
2
+
·
·
·
+
b
1
×
2
0
则
N=2×Q0+b0
N
=
2
×
Q
0
+
b
0
按这个过程依次进行下去可得
二进制小数
二进制小数可以表示为
2
2
的负幂之和。如果是一个实数,且
0<R<1
0
<
R
<
1
,则存在
d1
d
1
,
d2
d
2
,···,
dn
d
n
,···,满足
R=(d1×2−1)+(d2×2−2)+⋅⋅⋅+(dn×2−n)+⋅⋅⋅
R
=
(
d
1
×
2
−
1
)
+
(
d
2
×
2
−
2
)
+
·
·
·
+
(
d
n
×
2
−
n
)
+
·
·
·
其中
dj∈{0,1}
d
j
∈
{
0
,
1
}
,上式通常可以表示成二进制分数形式,如下:
R=0.d1d2⋅⋅⋅dn⋅⋅⋅⋅
R
=
0.
d
1
d
2
·
·
·
d
n
·
·
·
·
二进制小数转换为十进制数
即
R=(d1×2−1)+(d2×2−2)+⋅⋅⋅+(dn×2−n)+⋅⋅⋅
R
=
(
d
1
×
2
−
1
)
+
(
d
2
×
2
−
2
)
+
·
·
·
+
(
d
n
×
2
−
n
)
+
·
·
·
十进制小数转换为二进制小数
上式两边同乘2得
2R=d1+((d2×2−1)+⋅⋅⋅+(dn×2−n+1)+⋅⋅⋅)
2
R
=
d
1
+
(
(
d
2
×
2
−
1
)
+
·
·
·
+
(
d
n
×
2
−
n
+
1
)
+
·
·
·
)
上式右边的括号中的值式一个小于1的正数。因此
d1
d
1
是
2R
2
R
的整数部分,即
d1=int(2R)
d
1
=
i
n
t
(
2
R
)
,令上式的小数部分表示为
F1=frac(2R)=(d2×2−1)+⋅⋅⋅+(dn×2−n+1)+⋅⋅⋅
F
1
=
f
r
a
c
(
2
R
)
=
(
d
2
×
2
−
1
)
+
·
·
·
+
(
d
n
×
2
−
n
+
1
)
+
·
·
·
再对上式两边乘2,无限执行下去可得序列
{dk}
{
d
k
}
和
{Fk}
{
F
k
}
:
可通过下列收敛的几何级数:
R=∑∞j=1dj(2)−j R = ∑ j = 1 ∞ d j ( 2 ) − j
描述出 R R 的二进制小数表示。
计算机存储方式
整数###
无符号整数
无符号整数只包含正数。通常,对于使用位表示的无符号整数的表示范围为
0
0
到。
其中,具有最高权值的位被称为最高有效位(most significant bit),具有最低权值的位被称为最低有效位(least significant bit)。
有符号整数
有符号整数包含正数和负数,所以需要一种方法来区分正数和负数。
原码
原码表示法即在数值前面增加一位符号位,正数最高位为 0 0 ,负数最高位为,而 0 0 由两种表示,分别为和 −0 − 0 。对于原码表示法,一个数与其相反数之间的差别就是符号位不同。 r r 位二进制位表示范围位到 +2r−1−1 + 2 r − 1 − 1 。
反码
反码表示法即正数的反码与其原码相同,负数的反码即原码的符号位不变,其余各位按位取反,即对应正数的所有位按位取反得到,对于0,则反码表示法存在问题。对于反码表示法,一个数与其相反数之间按位互补。 r r 位二进制位表示范围为到 +2r−1−1 + 2 r − 1 − 1 。
补码
补码表示法即正数的补码就是它的原码本身,负数的补码是其反码加一。对于补码表示法,若求一个数的相反数的补码表示方法,可将该数的补码表示法按位取反之后再加一即可得到。对于
r
r
位二进制位,其表示范围一般位到
+2r−1−1
+
2
r
−
1
−
1
。
0
0
的补码仍为所有位均为,
−2r−1
−
2
r
−
1
的补码也是其本身。
在从补码得到十进制数的过程中,可视最高位的权重为
−2r−1
−
2
r
−
1
,其中
r
r
为表示二进制数的位数。
参考Wikipedia补码
对于4位二进制数,其表示的含义在不同编码格式下区别如下:
二进制表示 | 原码对应的数 | 反码对应的数 | 补码对应的数 |
---|---|---|---|
0000 | +0 | +0 | +0 |
0001 | +1 | +1 | +1 |
0010 | +2 | +2 | +2 |
0011 | +3 | +3 | +3 |
0100 | +4 | +4 | +4 |
0101 | +5 | +5 | +5 |
0110 | +6 | +6 | +6 |
0111 | +7 | +7 | +7 |
1000 | -0 | 无定义 | -8 |
1001 | -1 | -6 | -7 |
1010 | -2 | -5 | -6 |
1011 | -3 | -4 | -5 |
1100 | -4 | -3 | -4 |
1101 | -5 | -2 | -3 |
1110 | -6 | -1 | -2 |
1111 | -7 | 无定义 | -1 |
整数四则运算
对于指定比特字长,那么只有
2n
2
n
个值,加减法运算都存在上溢或者下溢的情况,实际上都等价于模
2n
2
n
的加减法运算。具体解释见Wikipedia补码。
对于补码,其加减运算只需要将其对应的二进制补码表示做二进制加减即可,如果两个正数相加后符号位为
1
1
或者两个负数相加符号位为,则说明发生溢出情况。
乘法也即将两个数的补码表示相乘,即可得积的补码表示,具体可见数论内容(模运算与余数)。
[x∗y]补=[x]补∗[y]补
[
x
∗
y
]
补
=
[
x
]
补
∗
[
y
]
补
实数
计算机使用规格化浮点二进制数表示实数,计算机中实际存放的是
x
x
的近似值,
其中数
q
q
称为尾数,是一个有限的二进制数,整数称为阶码,可以表达的二进制数的个数受
q
q
和的严格限制。
单精度浮点数
单精度浮点数格式是一种计算机数据格式,在计算机存储器中占用
4
4
个字节( bits),利用“浮点”(浮动小数点)的方法,可以表示一个范围很大的数值。
第
1
1
位表示正负,中间位表示指数,后
23
23
位储存有效数位(有效数位是
24
24
位)。
第一位的正负号
0
0
代表正,代表负。
中间八位共可表示
28=256
2
8
=
256
个数,用移码表示,对于
0
0
到,
1
1
到代表
−127
−
127
到
−1
−
1
,
127
127
代表零,
128∼255
128
∼
255
代表
1∼128
1
∼
128
。IEEE754规定浮点数表示法中的指数域的编码值为指数的实际值加上某个固定的值。这个固定的值被称为指数偏移值(exponent bias),大小为
2e−1−1
2
e
−
1
−
1
,其中
e
e
为存储指数的比特的长度。其中,当指数编码为0或者255时会有特殊含义,将在其后再次说明。
有效数位最左手边的并不会储存,因为它一定存在(二进制的第一个有效数字必定是
1
1
)。换言之,有效数位是位,实际储存
23
23
位。
上图表示的二进制数为:
sign=+1
s
i
g
n
=
+
1
exponent=−127+124=−3
e
x
p
o
n
e
n
t
=
−
127
+
124
=
−
3
fraction=1+2−2=1.25
f
r
a
c
t
i
o
n
=
1
+
2
−
2
=
1.25
value=sign×exponent×fraction=+0.15625
v
a
l
u
e
=
s
i
g
n
×
e
x
p
o
n
e
n
t
×
f
r
a
c
t
i
o
n
=
+
0.15625
当指数部分的编码值在
0<exponent≤2e−2
0
<
e
x
p
o
n
e
n
t
≤
2
e
−
2
,即0和指数部分编码值可表示的最大数除外时,此时分数部分最高有效位(即整数字)是
1
1
,分数部分的值为任意,那么这个浮点数被称为规约形式的浮点数,规约指用唯一确定的浮点形式表示一个值。
当指数部分的编码为,而分数部分不为
0
0
时,那么这个浮点数被称为非规约形式的浮点数,一般是某个数字相当接近零时才会使用非规约型式来表示。 IEEE 754标准规定:非规约形式的浮点数的指数偏移值比规约形式的浮点数的指数偏移值小。例如,最小的规约形式的单精度浮点数的指数部分编码值为
1
1
,指数的实际值为;而非规约的单精度浮点数的指数域编码值为
0
0
,对应的指数实际值也是而不是
−127
−
127
。即当指数部分编码为
0
0
且分数部分不为时,其对应的指数实际值为
1−(2e−1−1)
1
−
(
2
e
−
1
−
1
)
。实际上非规约形式的浮点数仍然是有效可以使用的,只是它们的绝对值已经小于所有的规约浮点数的绝对值;即所有的非规约浮点数比规约浮点数更接近
0
0
。规约浮点数的尾数大于等于且小于
2
2
,而非规约浮点数的尾数小于且大于
0
0
。一般使用非规约浮点数填补绝对值意义下最小规格数与之间的距离。
当指数部分为
0
0
且分数部分也为时,这个数为
±0
±
0
,正负号由符号位决定。
当指数部分为
2e−1
2
e
−
1
,且分数部分为
0
0
时,这个数表示,正负号由符号位决定。
当指数部分为
2e−1
2
e
−
1
,且分数部分为
0
0
时,这个数表示为不是一个数(NaN)。
(摘自Wikipedia)
双精度浮点数
双精度浮点数一般使用个比特位存储,1位作为符号位,11位作为指数位,52位作为小数位,其余规则和单精度相同。
具体可参照Wikipedia:
IEEE754
单精度浮点数
浮点数运算
浮点数加法
- 比较两数较小的指数,将较小的数进行右移,直到其指数与指数较大的相匹配。
- 尾数相加。(也可以在规约形式的整数位的前一位增加一个符号位,变补码即可实现减法)
- 对结果进行规格化,右移时增大指数,左移时减小指数。
- 上溢或者下溢,如果存在则抛出异常。
- 对尾数进行舍入,保留适当的数。
- 检查是否依旧为规格化的数,如果是,则结束,如果不是则跳到第3步。
浮点数乘法
- 对两个偏阶指数相加,然后减去偏阶值即可得到新的偏阶指数。
- 尾数相乘。
- 如果有需要,对乘积进行规格化:乘积右移,指数增大。
- 判断是否上溢或者下溢,如果是则抛出异常。
- 将尾数舍入到合适的位数。
- 检查其是否为规格化数,如果不是则跳到第3步。
- 如果操作数符号相同,设置积的符号为正,否则为负。