如何仅使用位移和加法进行乘法和除法运算?
要使用位移和加法进行乘法和除法运算,可以通过将其中一个数表示成二的幂的形式来进行乘法。如下所示:
21 * 5 = 10101_2 * 101_2 (初始步骤)
= 10101_2 * (1 * 2^2 + 0 * 2^1 + 1 * 2^0)
= 10101_2 * 2^2 + 10101_2 * 2^0
= 10101_2 << 2 + 10101_2 << 0 (分解)
= 10101_2 * 4 + 10101_2 * 1
= 10101_2 * 5
= 21 * 5 (与初始表达式相同)
如上所示,乘法可以通过加法和位移的分解和合并来实现。这也是为什么乘法比位移和加法花费更多时间的原因,它的时间复杂度为O(n^2),而不是O(n)。实际的计算机系统(与理论计算机系统相反)只有有限数量的位数,所以乘法所需的时间是加法和位移的固定倍数。如果我没记错的话,现代处理器在正确地进行流水线处理的情况下,可以通过调整处理器中的算术单元(ALU)的利用率,与加法的速度几乎一样快地进行乘法运算。
我知道这是一段时间前的问题了,但你能给出一个除法的例子吗?谢谢。
我同意,这个回答可能需要一些改进,因为它虽然对乘法给出了一个很好的答案,但没有完全回答问题,没有提到除法的方法。
如何只使用位移和加法进行乘法和除法?
这个问题的出现是因为有人想要实现乘法和除法的功能,但是只能使用位移和加法这两种操作。下面是解决这个问题的方法。
首先,我们可以使用位移操作来实现除法。具体来说,我们可以将除数的倒数以二进制形式表示出来,然后通过位移操作来计算商。
例如,对于除数为3的情况,我们可以表示为:0.0101 0101 0101 0101 0101 0101 0101 0101 .....
因此,对于一个数a除以3,我们可以这样计算商:(a >> 2) + (a >> 4) + (a >> 6) + ... + (a >> 30)
(针对32位运算)。
为了减少计算过程中的操作次数,我们可以将上述项合并:b = (a >> 2) + (a >> 4)
,b += (b >> 4)
,b += (b >> 8)
,b += (b >> 16)
。
除了上述方法,还有其他一些更有趣的方式来计算除法和取余操作。
如果问题的提出者指的是任意数字的乘法和除法,而不仅仅是常数除法,那么这个问题可能会有帮助:https://stackoverflow.com/a/12699549/1182653
通过利用模运算和蒙哥马利约简,可以实现整数常数的快速除法:What's the fastest way to divide an integer by 3?
感谢提供《Hacker's Delight》的参考!
额,是的,这个答案(常数除法)只是部分正确的。如果你尝试做 '3/3' 的除法,你会得到0。在《Hacker's Delight》中,他们实际上解释了这个问题并提出了一个补偿的错误解决方法。在这种情况下,我们可以这样计算:b += r * 11 >> 5
,其中 r = a - q * 3
。链接:hackersdelight.org/divcMore.pdf 页面2+。
需要澄清的是,这个答案的解决方案并不适用于一般情况下的除法,而是针对一些特殊常数除数的情况,例如除以3、除以5或除以7。答案中给出了一个除以3的示例。如果想了解更多,请查阅《Hacker's Delight》一书。