Bitwise operators 使用位移位运算符查找数字是否可被8整除
最近在一次采访中,我被要求只使用位移位运算符,编写一些代码,告诉你一个数字是否可以被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
x&7==0)测试低位n
位是否全部为零,或者更一般地说
x&((1UL对于二进制表示的任何整数,除以二的任意幂的余数就是低阶位的值,因此0b11001110
除以0b1000
就有余数0b110
。因此,为了检查是否可被8整除,需要检查三个低阶位是否都为零:
if (((x >> 3) << 3) == x)
divisibleBy8 = true;
if((x>>3)
或
if(!(numif(x&((1>3)在Java中,在不知道类型是long
还是int
的情况下,可以执行此技巧
if((x << -3) != 0)
if((xx检查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;