关于移码和浮点数
移码的英文是offset binary
它还有很多种叫法,可以看这里
Offset binary,[1] also referred to as excess-K,[1] excess-N, excess-e,[2][3] excess code or biased representation, is a method for signed number representation where a signed number n is represented by the bit pattern corresponding to the unsigned number n+K, K being the biasing value or offset.
这里有几个关键点:
1.移码是针对有符号数的一种编码。
2.移码的编码是说把原来的二进制编码再加上一个另外的一个数,这就叫移码。只要你多加了,就叫移码,不是说非得加128或127才叫移码,你加3也叫移码,比如余三码里面,要给结果加3,这种也叫移码。
There is no standard for offset binary,
but most often the K for an n-bit binary word is K = 2n−1 (for example, the offset for a four-digit binary number would be 8).
意思是移码并没有统一的标准,加多少都可以的。
This has the consequence that the minimal negative value is represented by all-zeros,
the "zero" value is represented by a 1 in the most significant bit and zero in all other bits,
and the maximal positive value is represented by all-ones (conveniently,
this is the same as using two's complement but with the most significant bit inverted).
用了移码表示有这样的好处。
如果用移码表示的话,比如四个二进制位,最小的那个负数就是0000,最大的那个数就是1111。
. It also has the consequence that in a logical comparison operation,
one gets the same result as with a true form numerical comparison operation,
whereas, in two's complement notation a logical comparison will agree with true form numerical comparison operation
if and only if the numbers being compared have the same sign. Otherwise the sense of the comparison will be inverted,
with all negative values being taken as being larger than all positive values.
意思是说,有了移码可以保证逻辑比较运算符和算数比较运算符的结果是一致的。
说实话我没有看懂,啥是逻辑比较运算符? 算数比较运算符就是大于小于这些。
但我觉得可能是这样的意思。
我们可以用逻辑操作来比较两个数大小的,比如移位操作,
比如比较1110 和1010 这两个数,假设它们都是补码存储的,从左到右除了符号位之外每次从前面那个数取一个二进制位,同时也从后面那个数取一个二进制位,这种操作应该可以用移位操作完成的。如果取到(1,0),那么就证明前面的那个数的绝对值是大的,那根据补码的规则,绝对值大的对应的真数反而小,因为它经过了反码,那这种感觉就和我们算数比较的结果是相悖的,我们算数比较的依据是,你绝对值大,那么你对应的数就大。
有了移码之后
1110 经过移码编码之后就是0110,1010经过移码编码之后就是0010。
0110 和0010,你很容易就看出哪个数大,哪个数小。
我在一篇pdf里面找到了一些观点。
搜索关键字:Episode-3.05-Transcript.pdf
In computing, this lexicographical order is important. There are times when computers must compare or
sort values. The circuitry to do this is simple if the patterns of ones and zeros are ordered from all zeros
representing the lowest value to all ones representing the highest. To compare two binary values, we
start with the left-most bit, and moving left to right, look for the first pair of bits where one of the bits is
a one and the other is a zero. The pattern containing the one is the larger of the two values.
This brings us to biased notation. Biased notation takes the ordered patterns of ones and zeros and
shifts them along the integer number line so that the pattern of all zeros is equivalent to the offset or
bias. Before doing any conversions, we need to define a bias, sometimes identified as K. This means that
the pattern of all zeros in biased notation using an offset of K is negative K. The remaining values
increment up from negative K
意思是说 字典序很重要,比较数字的时候很常用。
我在zhihu上也看到类似的观点,说是移码在比较数字大小这方面很方便。相当于把
[-127,-1] 映射到了[1,127] ,你负数不好比较大小,正数就好比较了呗,大概是这意思,我觉得这还挺好理解的。
有的网友也提出了不一样的观点,说两个数比较大小,用CMP指令或者SUB指令就可以了,这不很简单的事情吗? 而且补码就可以直接用CMP和SUB指令计算,为什么需要移码?
我也挺疑惑的。
我还有一个小的疑问,既然移码这么方便比较数大小,为什么只用在了浮点数,为什么不把正数都用移码来表示呢?
我目前确实没体会到移码的好处,好像和我们关系不太大,都是计算机直接帮我们给处理了。但我觉得平常有个小技巧可能会有用,就是比较两个数大小,比如1101,和1111,这两个数,哪个大,哪个小,换成移码0101 0111,很明显后者大,确实很方便。
说完了移码再说浮点数。
先来说几个概念
定点整数,就是纯整数,比如15.0,1560.0
定点小数,就是纯小数,比如0.1,0.1567
对于定点整数和定点小数我们完全可以按照整数的方式来存储,就是补码那一套规则存储即可。
但是如果遇到-15.3456789 这种数,究竟 该怎么存储,这是一个问题。
假设有32个二进制位来存储这个数,究竟该分配多少个二进制位来存储整数部分,多少个二进制位来存储小数部分。
-15.3456789=-15+(-0.3456789)
那是不是要把这两个负数都得存储起来。假设我们给整数部分分配8个二进制位(其中一位是符号位),小数部分来存储25个二进制位(其中一位是符号位)。
8个二进制位,可以表示[-128,127]这些数,能表示的数的范围太小了呀。
那,要不给整数部分分配16个二进制位,可以表示[-32768,32767],这范围也太小了呀,而且你给整数分配的二进制位多了,那么意味着小数部分的精度就小了。
为什么用整数的存放方法俩存储分数,表示的范围这么少呢? 因为没有采用科学计数法
IEEE754其实就是针对分数的科学计数法。
这个标准规定了,你必须把数先写成2的几次方 乘以某个小数的这种形式。然后存储数据的时候,只存储几次方的那个数据,假设我们分配8个二进制位来表示,那么就可以表示2的-128到2的127 这个范围的数,这个存储实数的方法比我们存储整数那个方法好太多了,表示的范围大太多了。

