计算机的算术表示

计算机的算术表示

整数表示

无符号数

计算机中的数字都由0与1表示,给定一串01序列,将其转换为无符号数的十进制
记序列为
X n − 1 X n − 1 X n − 2 X . . . X 0 X_{n-1}X_{n-1}X_{n-2}X_{...}X_0 Xn1Xn1Xn2X...X0
其中 X i X_i Xi的取值为0或1,则其对应的十进制值是
U n s i g n e d V a l u e = ∑ k = 0 n − 1 X k ∗ 2 k UnsignedValue = \sum_{k=0}^{n-1}X_k*2^k UnsignedValue=k=0n1Xk2k
无符号数的最大值(记为U m i n ) {min}) min)与最小值(记为 U m a x U_{max} Umax)为:
U m i n = 0    ⟺    X k = 0 k = 0 , 1 , 2... U_{min} = 0 \iff X_k = 0 \\ k = 0, 1, 2 ... Umin=0Xk=0k=0,1,2...

U m a x = ∑ k = 0 n − 1 2 k = 2 n − 1    ⟺    X k = 1 k = 0 , 1 , 2... U_{max} = \sum_{k = 0}^{n-1}2^k = 2^n - 1 \iff X_k = 1 \\ k = 0, 1, 2 ... Umax=k=0n12k=2n1Xk=1k=0,1,2...

有符号数

有符号数可以带正负号,最高位为符号位,1为负,0为正。无符号有两种典型的表示方法,第一种是补码,第二种是原码。当今机器上的有符号数全部用补码表示,但是由于补码不是很好理解,所以往往也会用原码充当中间层:补码转为原码,再用原码来理解。

此处只给出将无符号的01序列转为对应的十进制值公式:
S i g n e d V a l u e = ( − 1 ) ∗ 2 n − 1 ∗ X n − 1 + ∑ k = 0 n − 2 X k ∗ 2 k SignedValue = (-1)*2^{n-1}*X_{n-1}+\sum_{k=0}^{n-2}X_k*2^k SignedValue=(1)2n1Xn1+k=0n2Xk2k
此公式表明:对于负数来说,最高位是符号位为1,其他位越小,则该负数越小,当其他位为0时,值最小,为 − 2 n − 1 -2^{n-1} 2n1.同样,对于正数来说,当 X n − 1 X_{n-1} Xn1为0,也就是符号位为0,其他位全1时最大。

补码表示的最小值 T m i n T_{min} Tmin与最大值$T_{max}为
T m i n = − 2 n − 1 T m a x = ∑ k = 0 n − 2 2 k = 2 n − 1 − 1 T_{min} = -2^{n-1}\\ T_{max} = \sum_{k = 0}^{n - 2}2^k = 2^{n-1} - 1 Tmin=2n1Tmax=k=0n22k=2n11
可以观察到补码的最小值比最大值的相反数还要小一,所以 T m i n T_{min} Tmin常作为测试数据验证一些程序

有符号数性质公式

最小值等于最大值的相反数减一

T m i n = − T m a x − 1 ​ T_{min} = -T_{max}-1​ Tmin=Tmax1​

负数的重复的前导一可以删去

比如二进制位 1111111111000000 , 前面重复了10个1, 这些重复的1可以删去只留下一个,也就是说 1111111111000000 = 1000000
对于二进制数 X n − 1 X n − 1 X . . . X 0          i f    X k = 1     ( k = i , i + 1 , . . . , n − 1 ) t h e n    X n − 1 X n − 1 X . . . X 0 = X i X i − 1 X . . . X 0 对于二进制数X_{n-1}X_{n-1}X{...}X_{0} \ \ \ \ \ \ \ \ \\ if\ \ X_{k} = 1 \ \ \ (k = i, i+1, ...,n-1)\\ then\ \ X_{n-1}X_{n-1}X{...}X_{0} = X_{i}X_{i-1}X{...}X_{0} 对于二进制数Xn1Xn1X...X0        if  Xk=1   (k=i,i+1,...,n1)then  Xn1Xn1X...X0=XiXi1X...X0
证明
X n − 1 X n − 1 X . . . X 0 = ( − 1 ) ∗ 2 n − 1 + ∑ k = 0 i − 1 X k ∗ 2 k + ∑ k = i n − 2 2 k = ∑ k = 0 i − 1 X k ∗ 2 k + ( ( − 1 ) ∗ 2 n − 1 + ∑ k = i n − 2 2 k ) = ∑ k = 0 i − 1 X k ∗ 2 k + ( − 1 ) ∗ 2 i = X i X i − 1 X . . . X 0 \begin{split} X_{n-1}X_{n-1}X{...}X_{0} \\ &= (-1)*2^{n-1}+\sum_{k=0}^{i-1}X_k*2^k + \sum_{k = i}^{n - 2}2^k \\ &= \sum_{k=0}^{i-1}X_k*2^k + ((-1)*2^{n-1}+\sum_{k = i}^{n - 2}2^k)\\ &= \sum_{k=0}^{i-1}X_k*2^k + (-1)*2^i \\ &= X_{i}X_{i-1}X{...}X_{0} \end{split} Xn1Xn1X...X0=(1)2n1+k=0i1Xk2k+k=in22k=k=0i1Xk2k+((1)2n1+k=in22k)=k=0i1Xk2k+(1)2i=XiXi1X...X0
得证

一个数的相反数等于其反码+1

证明:
X n − 1 X n − 1 X . . . X 0 = ( − 1 ) ∗ 2 n − 1 ∗ X n − 1 + ∑ k = 0 n − 2 X k ∗ 2 k X n − 1 ‾   X n − 1 ‾   X . . . ‾   X 0 ‾ = ( − 1 ) ∗ 2 n − 1 ∗ ( 1 − X n − 1 ) + ∑ k = 0 n − 2 ( 1 − X k ) ∗ 2 k = − 2 n − 1 + ∑ k = 1 n − 2 2 k + ( − 1 ) ∗ [ ( − 1 ) ∗ 2 n − 1 ∗ X n − 1 + ∑ k = 0 n − 2 X k ∗ 2 k ] = − 1 − X n − 1 X n − 1 X . . . X 0 \begin{split} X_{n-1}X_{n-1}X{...}X_{0} &= (-1)*2^{n-1}*X_{n-1}+\sum_{k=0}^{n-2}X_k*2^k \\ \overline{X_{n-1}}\ \overline{X_{n-1}}\ \overline{X{...}}\ \overline{X_{0}} &= (-1)*2^{n-1}*(1-X_{n-1})+\sum_{k = 0}^{n-2}(1-X_k)*2^k \\ &= -2^{n-1}+\sum_{k = 1}^{n-2}2^k + (-1)*[(-1)*2^{n-1}*X_{n-1}+\sum_{k=0}^{n-2}X_k*2^k] \\ &= -1 - X_{n-1}X_{n-1}X{...}X_{0} \end{split} Xn1Xn1X...X0Xn1 Xn1 X... X0=(1)2n1Xn1+k=0n2Xk2k=(1)2n1(1Xn1)+k=0n2(1Xk)2k=2n1+k=1n22k+(1)[(1)2n1Xn1+k=0n2Xk2k]=1Xn1Xn1X...X0
因此 − X n − 1 X n − 1 X . . . X 0 = X n − 1 ‾   X n − 1 ‾   X . . . ‾   X 0 ‾ + 1 得证 因此 - X_{n-1}X_{n-1}X{...}X_{0} = \overline{X_{n-1}}\ \overline{X_{n-1}}\ \overline{X{...}}\ \overline{X_{0}}+1得证 因此Xn1Xn1X...X0=Xn1 Xn1 X... X0+1得证
得证

有符号数与无符号数之间的转换
常见转换方式

B2U:B指的是binary二进制,2在英文中常指的是to,U指的是unsigned 无符号数,所以这个术语的意思是将二进制转换为一个无符号数,本质上是一个映射,用函数来理解的话就是,传进去一个二进制参数,经过B2U这个函数(映射),返回值是一个无符号数。显然,B2U的本质就是上面的公式
B 2 U ( X n − 1 X n − 1 X n − 2 X . . . X 0 ) = ∑ k = 0 n − 1 X k ∗ 2 k B2U(X_{n-1}X_{n-1}X_{n-2}X_{...}X_0) = \sum_{k=0}^{n-1}X_k*2^k B2U(Xn1Xn1Xn2X...X0)=k=0n1Xk2k
注意:这里需要把 ∑ k = 0 n − 1 X k ∗ 2 k \sum_{k=0}^{n-1}X_k*2^k k=0n1Xk2k当成一个数来看待

B2T: T常指有符号数,所以,B2T如下所示
B 2 T ( X n − 1 X n − 1 X n − 2 X . . . X 0 ) = ( − 1 ) ∗ 2 n − 1 ∗ X n − 1 + ∑ k = 0 n − 2 X k ∗ 2 k B2T(X_{n-1}X_{n-1}X_{n-2}X_{...}X_0) = (-1)*2^{n-1}*X_{n-1}+\sum_{k=0}^{n-2}X_k*2^k B2T(Xn1Xn1Xn2X...X0)=(1)2n1Xn1+k=0n2Xk2k
U2T: 给定一个无符号数,通过T2U映射以后,返回一个有符号数。可以利用复合函数的知识,利用上面两个B2U和B2T映射来推导这个映射
尝试用逆映射推导: U 2 T = B 2 T ( U 2 B ) = ( B 2 T ) ( B 2 U ) − 1 但是不好求逆映射 第二种方法: B 2 U − B 2 T = X n − 1 ∗ 2 n − 1 + 2 n − 1 ∗ x n − 1 = X n ∗ 2 n 所以 B 2 T = B 2 U − X n ∗ 2 n 此处的 B 2 U 代指的是 B ( X n − 1 X n − 1 X . . . X 0 )所对应的无符号数, B 2 T 代指的是 B ( X n − 1 X n − 1 X . . . X 0 )所对应的有符号数 所以 U 2 T ( u 0 ) = t 0 = u 0 − X n ∗ 2 n 尝试用逆映射推导:U2T = B2T(U2B) = (B2T)(B2U)^{-1}但是不好求逆映射 \\ 第二种方法:B2U - B2T = X_{n-1}*2^{n-1}+2^{n-1}*x_{n-1} = X_{n}*2^{n} \\ 所以 B2T = B2U - X_{n}*2^{n} \\ 此处的B2U代指的是B(X_{n-1}X_{n-1}X{...}X_{0})所对应的无符号数,\\ B2T代指的是B(X_{n-1}X_{n-1}X{...}X_{0})所对应的有符号数 \\ 所以 U2T(u_{0})= t_{0} = u_{0} - X_{n}*2^{n} 尝试用逆映射推导:U2T=B2T(U2B)=(B2T)(B2U)1但是不好求逆映射第二种方法:B2UB2T=Xn12n1+2n1xn1=Xn2n所以B2T=B2UXn2n此处的B2U代指的是BXn1Xn1X...X0)所对应的无符号数,B2T代指的是BXn1Xn1X...X0)所对应的有符号数所以U2T(u0)=t0=u0Xn2n
上面的推导利用了 U 与 T 具有相同的二进制表示(B)

理解,对于正数来说, X n X_{n} Xn为0,则 t 0 = u 0 t_{0} = u_0 t0=u0,也就是正数的无符号数与有符号数是相同的

对于负数来说,有符号数等于无符号数减去

t 0 = { u 0 , u 0 < = T m a x u 0 − 2 n , u 0 > T m a x 或等价的 u 0 > = 2 n − 1 t_{0} =\begin{cases} u_{0} , & u_{0} <= T_{max} \\ u_{0} - 2^n, & u_{0} > T_{max} 或等价的 u_{0} >= 2^{n-1} \end{cases} t0={u0,u02n,u0<=Tmaxu0>Tmax或等价的u0>=2n1

T2U : T2U 其实就是U2T的逆过程,稍微移项即可得到。下面图像的单向箭头用双向箭头其实更为贴切,这是一个双射。
u 0 = { t 0 , t 0 > 0 t 0 + 2 n , t 0 < 0 u_{0} = \begin{cases} t_{0} ,&t_{0} > 0 \\ t_{0}+2^n, &t_{0} < 0 \end{cases} u0={t0,t0+2n,t0>0t0<0
下面的一张图片非常便于记忆 (原创图片,简单了点,求大神完善🐶)

符号数与无符号数的转换

核心归纳:无符号与有符号的差是 2 n 2^{n} 2n, 需要 减去 2 n 2^{n} 2n的临界值是 2 n − 1 2^{n-1} 2n1时,不是 2 n − 1 − 1 2^{n-1} - 1 2n11

浮点数表示

背景介绍:现今世界上的绝大多数机器运行的浮点数都是采用了IEEE754标准,这个标准规定了浮点数如何进行编码,这个标准是由UCB(加州伯克利,四大CS神校之一,🏫)的教授指定。

浮点数的组成

浮点数采用科学计数法的思想,将一个带有小数的浮点数先进行移位,比如 234.53移位为 2.3453 ∗ 1 0 2 2.3453*10^2 2.3453102,只保留一位个位数,当然,对于二进制而言,-10011.101移位为 -1.0011101* 2 4 2^4 24,所以一个浮点数被分成三部分,分别是符号位,阶码(2的幂数,比如上面的4),尾数(上面的1.0011101),分别用S, E, F来表示,所以核心任务便是如何用二进制串来存储S, E, F.

容易想到,将二进制的最高位设置为符号位,紧随其后的几位设置为E的补码,最后的几位设置为F的补码,但是采用这种方式编码的效果不好,精度低,不够巧妙。所以接下来就引入IEEE754标准的编码方式。

后续中统一对S的编码用s (sign)表示,对E的编码用e (exp)表示,对F的编码用f (frac)表示
浮点数 V a l u e = ( − 1 ) S ∗ F ∗ 2 E 浮点数Value = (-1)^S*F*2^E 浮点数Value=(1)SF2E

下面是对 float 和 double 的编码组成表示

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HqaorrUr-1664542987155)(F:\笔记\体系结构\1_tu8UHXww5mM6ndUVNA_dAg.png)]

由于float和double的原理都是一模一样的,所以只对float进行介绍,double完全一样。

规格化与非规格化

IEEE754标准中浮点数分为4种,分别为非规格化、规格化、无穷大、NaN(not a number), 根据 e 和 f的值来进行区分的。下面这张图必须背下来,必考

四种浮点类型

规格化的数

s 决定了符号,1为负,0为正, S = s;

为了计算E,需要引入一个叫bias(偏差)的概念, IEEE754中,因为s表示符号位,而E的正负是与s无关的,为了表示E的正负, 使用E = B2U(e) - bias 来表示E的值,对于规格化的数来说,
b i a s = 2 n − 1 − 1 bias = 2^{n-1}-1 bias=2n11
其中n为阶码(e)的总位数,比如float 为8

简记为 E = e - bias

非规格化的数字的另一个特点就是所有数开头都有一个隐含的一,啥意思呢?看例子
0.01101 = 1.101 * 2 2 2^{2} 22
110.1001 = 1.101001 * 2 − 2 2^{-2} 22
对于规格化的数,一定是将其化为1.***的形式,其中***就是F,小数部分,也是我们要编码的对象,所以对于所有规格化的数字都有这个前导的1,因此,这个前导的1就可以不用再编码,只要是规格化的数字都默认加上即可。

小数部分的编码:
F = B 2 U ( f ) + 1 F = B2U(f) + 1 F=B2U(f)+1
其中f 是二进制编码串,通过B2U的映射变为无符号数即可,注意,因为这是小数部分,所以乘的应该是 2 − 1 2^{-1} 21
X n − 1 X n − 1 X n − 2 X . . . X 0 = ∑ k = 0 n − 1 X k ∗ 2 − k X_{n-1}X_{n-1}X_{n-2}X_{...}X_0 = \sum_{k=0}^{n-1}X_k*2^{-k} Xn1Xn1Xn2X...X0=k=0n1Xk2k
理解这一点的关键是理解二进制串前面还有一个隐含的小数点。

规格化对应实数中不是特别小也不是特别大的数字

非规格化的数字

S = s ; E = 1 − b i a s ; b i a s = 2 k − 1 − 1 ; F = B 2 U ( f ) S = s; \\ E = 1 - bias; \\ bias = 2^{k-1} - 1; \\ F = B2U(f) S=s;E=1bias;bias=2k11;F=B2U(f)

  1. 和规格化的数相比,它的E发生了变化,变为了 1- bias 而不是 e -bias (0 - bias );
    2. 其次,F没有开头隐含的1了。

这两个变化是为了在最小的规格化数与最大的非规格化数之间形成一种平滑的过渡。为了更深入的理解这一点,有兴趣的可以自己算一下最小的规格化数和最大的非规格化数。

非规格化对应特别小,特别接近0的数字

无穷大和NaN

当s 为0 ,为正无穷, s 为1, 为负无穷。NaN 能够认出来即可

总结

一表胜千言

类型SeEbiasF
规格化se不全为0e - bias, 2 n − 1 − 1 2^{n-1}-1 2n111 + f
非规格化se全为01 - bias, e全为0 2 n − 1 − 1 2^{n-1}-1 2n11f
无穷大se全1f全为0
NaNse全1f不全为0

浮点数 V a l u e = ( − 1 ) S ∗ F ∗ 2 E 浮点数Value = (-1)^S*F*2^E 浮点数Value=(1)SF2E

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值