背景
我对布尔逻辑很感兴趣,并了解事物的工作原理。我正在解决我在网上找到的一些问题here。
我特别难以除以2的幂。我尝试了解决方案,但我仍然无法理解正在发生的事情。
/*
* divpwr2 - Compute x/(2^n), for 0 <= n <= 30
* Round toward zero
* Examples: divpwr2(15,1) = 7, divpwr2(-33,4) = -2
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 15
* Rating: 2
*/
int divpwr2(int x, int n) {
int xMSB = ((x>>31) & 1);
int bias = xMSB;
bias = bias << n;
bias += ((xMSB<<31) >>31);
return ((x + bias) >> n);
}
我所知道/问题:
所以根据我的理解,如果你需要乘法,你可以将位移到左边。如果要分割,则需要将位移到右侧。这会让我觉得我需要做类似的事情:
x >> (2 << n)
然而,由于2的补码,它不可能是直截了当的。我需要确定x是正还是负。我可以通过找到最重要的位来做到这一点。你可以通过向右移动31来做到这一点。这是我开始遇到麻烦的地方:
15&gt;&gt; 31 /// MSB = 0
-33&gt;&gt; 31 /// MSB = 1
如果我计算0&amp; 1,那就是0.如果我做1&amp; 1,那就是1.
问题1:在& 1
使用((x>>31) & 1);
有什么意义?
问题2:此外,MSB乘以n bias = bias << n;
的重点是什么?
为什么不跳过这两个步骤:
bias = bias << n;
bias += ((xMSB<<31) >>31);
我的逻辑是,如果我将偏差乘以n(bias = bias << n;
),如果MSB为0,我得到0.如果偏差是1,我得到n。所以,我试图删除这些行,我仍然得到给定测试参数的正确答案:
public int divpwr2(int x, int n) {
int xMSB = ((x>>31) & 1);
return ((x + xMSB) >> n);
}
但是,我已经看了一些其他类似的解决方案,我想知道,这两行中有什么东西我需要逻辑明智而忽略了吗?
这不是作业。我只是想了解更多有关布尔逻辑以及事物如何工作的信息。我知道有一些类似的问题,我只是没有找到任何可以解答我问题的东西。