以数字91为例。这个数字的二进制是1011011。如果你把这个数字向右移动5位,你会得到2(二进制的10)。根据谷歌搜索,向左或向右移动一定位数的位相当于将一个数字乘以或除以2的位数的次方。通过位移位从91到2,方程是这样的:91 / 2^5
,也就是91 / 32
。当然,如果你用计算器算的话,会有一些小数,在位移位的时候是不包括的。得到的2实际上是2.84357
。我相信你知道如果你对一个数字做了一个特定的运算,然后你做逆运算,结果会是你最初得到的。那么这和十进制精度有关系吗?
向右移动有一个数学上的等价…和数学运算为UNRECOVERABLE.
你似乎认为向右移动是:
位向左或向右移动一定位相当于将数字乘以或除以2
这是你会听到人们随便说的话,但它只对了一半。因为它不是相同的但只有类似.
正确的语句是:
将一个以2为基数的数字向右移动一位相当于在整数域中除以2
如果你有一个整数计算器,如果你做91/32
,你会得到2
。你不会得到任何小数点,因为我们是在整数域操作。
对于实数,等效运算为:
FLOOR(91/32)
这也是不可恢复的,因为它也会导致2
。
这里的教训是在听别人随便说的话时要小心. 随意的讲话通常不精确,并且假设听者熟悉主题。您需要更深入地挖掘语句是什么实际上我想说。
至于为什么不可恢复?整数除法有两种结果:商(这是主要结果)和余数. 当我们用91
除以32
时,我们这样做:
2
_____
32 ) 91
64
__
27
我们得到2
的结果和27
的余数。2*32
相乘不能得到91
的原因是我们丢掉了余数。
如果您保存了剩余部分,则可以返回结果。然而,计算余数并不是简单的移位问题。下面是一个如何在C中使其可逆的示例:
int test () {
int a = 91;
int b = 32;
int result;
int remainder;
result = a / b; // result will be 2
remainder = a % b; // remainder will be 27
return (result * b) + remainder; // returns 91
}
如果输入和输出之间有1-1映射,即它有反函数,则只能恢复操作的结果。但并不是所有的数学函数都有反函数
例如,如果f(x) = x >> n
和>>
是移位运算符,那么它就等于
f(x) =⌊x/2n⌋
with⌊⌋作为底函数。由于有许多输入,导致相同的输出关系不是1-1,也不可能有反函数。这个函数对于有符号右移和无符号右移都是一样的:
91 >> 5 == floor(91.0/32.0) == 2
-91 >> 5 == floor(-91.0/32.0) == -3
同样,对于无符号左移位函数g(x) = x << n
,其等效值为
g (x) = (x * 2<一口>n> n一口>
,其中N为x的位大小,因为硬件,C和许多其他语言中的整数数学总是减少模2N由于寄存器大小的限制和使用2的补码。很明显,模函数也不是可逆的/可恢复的。带符号的左移几乎是相同的,只有一些小的修改