Bitwise operators 使用位移位运算符查找数字是否可被8整除

Bitwise operators 使用位移位运算符查找数字是否可被8整除,bitwise-operators,bit-shift,Bitwise Operators,Bit Shift,最近在一次采访中,我被要求只使用位移位运算符,编写一些代码,告诉你一个数字是否可以被8整除,显然代码很短——有人有线索吗 注意:如果不需要使用移位,则应使用掩码(如x&7==0)测试低位n位是否全部为零,或者更一般地说 x&((1UL对于二进制表示的任何整数,除以二的任意幂的余数就是低阶位的值,因此0b11001110除以0b1000就有余数0b110。因此,为了检查是否可被8整除,需要检查三个低阶位是否都为零: if (((x >> 3) << 3) == x) d

最近在一次采访中,我被要求只使用位移位运算符,编写一些代码,告诉你一个数字是否可以被8整除,显然代码很短——有人有线索吗

注意:如果不需要使用移位,则应使用掩码(如
x&7==0)测试低位
n
位是否全部为零,或者更一般地说
x&((1UL对于二进制表示的任何整数,除以二的任意幂的余数就是低阶位的值,因此
0b11001110
除以
0b1000
就有余数
0b110
。因此,为了检查是否可被8整除,需要检查三个低阶位是否都为零:

if (((x >> 3) << 3) == x)
  divisibleBy8 = true;
if((x>>3)
或


if(!(num
if(x&((1>3)在Java中,在不知道类型是
long
还是
int
的情况下,可以执行此技巧

if((x << -3) != 0)

if((x
x检查n被9整除的最简单的方法是执行n%9。
另一种方法是对n的数字求和。如果数字之和是9的倍数,则n是9的倍数。
上述方法不是基于位运算符的方法,需要使用“%”和“/”。位运算符通常比模运算符和除法运算符快。下面是一种基于位运算符的方法,用于检查9的可除性

你应该检查这个链接
为了简单起见

如果要确定任意给定整数N是否为X的倍数,即X是2的幂,只需执行以下操作:

    public static boolean isMultipleOfpowerOf2(int n, int x) {
    if((n&(x-1))==0){
       return true;
    }else {
        return false;
    }
}
为什么要这样做

考虑X=8

8:        1000*
9:        1001
10:       1010
11:       1011
12:       1100
13:       1101
14:       1110
15:       1111***
16:      10000*
17:      10001
18:      10010
19:      10011
20:      10100
21:      10101
22:      10110
23:      10111***
24:      11000*
现在您可以清楚地看到,8的任何倍数都不使用3*正确位,这对于2的所有幂都是正确的。 你可以看到,X-1,7,使用了所有这些位***

剩下的很简单,你可以用&(X-1)屏蔽掉所有其他的位,如果答案是零,那么你就有了一个倍数

N & (X-1) with  N = 9, X=8

N(9)    = 1001
X(8-1)  = 0111
N&(X-1) = 0001  this case is != 0

N(16)   = 10000
X(8-1)  = 00111
N&(X-1) = 00000  this time is == 0, it is a multiple.
有关这方面的更多信息,请参阅这篇非常好的文章:

如果((x>>3)提示,右移与除以相同2@SteveKuo在C中,只有正整数和8是2*2*2;)“AUAH有符号保持右移。我相信C语法是代码> Num > > 3代码/ @代码。@ SergYLL。-这是java语法。在C和C++中没有符号保持负值的右移;负数的右移具有实现定义的行为。这不仅仅是使用位移位函数OK,不确定有多少强调。“移位”是。有些人倾向于混淆术语。从好的方面来说,它是有效的,而且是最快的解决方案。-“位移位”怎么可能意味着其他任何东西呢?在这种情况下,“按位”实际上是指,只是没有精确表示。这不是“可被4整除”吗"你知道我脑子里有一个类似的答案,我没有提到我的想法,因为我认为这可能是错误的,为什么我要隐瞒?让我确认一下works@godzilla因为
12的幂3是8。一个数字可以被8整除当且仅当最低值三位为零。嗯…这依赖于比较两个数字,比较(即减法)并不是字面意义上的移位操作。@PeterLawrey的问题带有C标记,它是有效的C。你对java是正确的。这两个表达式都会触发C中未定义的行为。@ouah我相信大多数C程序都广泛使用未定义的Behvaior。我很确定这是未定义的(或实现定义,或其他一些“如果您希望代码始终在任何平台上工作,请不要这样做”),因此可能不一定会工作。@Matstpeterson它是定义的,并且将在所有JVM上工作,无论是32位还是64位。Java倾向于定义它的所有边缘情况,与一些旧的语言不同。;)对不起,我的观点是这样的“这只适用于Java以外的其他语言中的某些情况”。@MatsPetersson这在C中是未定义的行为。我认为,JLS3 15.19可以这样解释。“这就好像右侧操作数使用了位逻辑AND运算符&掩码值为0x1f。”这就是(唯一?)正确的答案。
if(! (num << 29) ) { // assuming num is 32 bits
    // num divisible by 8
}
if (x & ((1 << 3)-1) == 0)
if (x == ((x >> 3) << 3))
if((x << -3) != 0)
    public static boolean isMultipleOfpowerOf2(int n, int x) {
    if((n&(x-1))==0){
       return true;
    }else {
        return false;
    }
}
8:        1000*
9:        1001
10:       1010
11:       1011
12:       1100
13:       1101
14:       1110
15:       1111***
16:      10000*
17:      10001
18:      10010
19:      10011
20:      10100
21:      10101
22:      10110
23:      10111***
24:      11000*
N & (X-1) with  N = 9, X=8

N(9)    = 1001
X(8-1)  = 0111
N&(X-1) = 0001  this case is != 0

N(16)   = 10000
X(8-1)  = 00111
N&(X-1) = 00000  this time is == 0, it is a multiple.
if (((x >> 3) << 3) == x)
    divisibleBy8 = true;