【问题标题】:find if a number is divisible by 8 - using bit shifting operators查找数字是否可被 8 整除 - 使用位移运算符
【发布时间】:2020-06-03 15:01:34
【问题描述】:

我最近在一次采访中被问到,只使用位移运算符,编写一些代码来告诉你一个数字是否可以被 8 整除,显然代码很短 - 有人知道吗?

注意:如果您不需要使用移位,您可以使用x&7 == 0 之类的掩码或更一般地测试低 n 位是否为全零 x & ((1UL << n) - 1) == 0How can I tell if a number is a multiple of four using only the logic operator AND?

【问题讨论】:

  • 提示,右移等同于除以2
  • @SteveKuo 在 C 中,仅适用于正整数
  • 而 8 是 2 * 2 * 2 ;)
  • @ouah 有符号保持右移。我相信 C 语法是num >>> 3
  • @SergeyL。 - 那是 Java 语法。在 C 和 C++ 中,没有负值的符号保持右移;负数的右移具有实现定义的行为。

标签: bitwise-operators bit-shift


【解决方案1】:

对于以二进制表示的任何整数,除以任何 2 的幂的余数就是低位的值,因此 0b11001110 除以 0b1000 有余数 0b110。因此,为了检查是否可被 8 整除,您需要检查三个低位是否全为零:

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

右移先清除后三位,左移恢复大小,再与原数比较。

正如其他人指出的那样,如果您知道整数的位宽,您可以这样做

if (!(x<<29))
  divisibleby8 = true;

将 29 替换为 61 以获得 64 位整数等。显然在 Java 中您可以这样做:

if ((x << -3) != 0)
  divisibleby8 = true;

因为像-3 这样的负移位被解释为bit_width - 3,它适用于 32 位和 64 位整数。

(你不需要所有的括号,为了清楚起见我已经包括在内)

只是为了完整性

这些都是测试被 8 整除的非常糟糕的方法。执行if !(x &amp; 7) 更清晰,几乎可以肯定同样快或更快。

【讨论】:

  • 那不是“能被 4 整除”吗?
  • 你知道我脑子里有一个类似的答案,我没有提到我的想法,因为我认为它可能是错误的,我为什么要隐瞒?让我确认这是有效的
  • @godzilla 因为1 &lt;&lt; 3 == 8
  • 2 的 3 次方是 8。当且仅当最低三位为 0 时,一个数字可以被 8 整除。
  • 嗯...这依赖于比较两个数字,比较(即减法)并不是字面意义上的位移操作。
【解决方案2】:
int num;

if(!(num & 7)) {
     // num divisible by 8
}

if(! (num << 29) ) { // assuming num is 32 bits
    // num divisible by 8
}

【讨论】:

  • @PeterLawrey 问题带有 C 标签,它是有效的 C。你适合 java。
【解决方案3】:

在 Java 中,不知道类型是 long 还是 int 你可以这样做

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

这将根据该类型移动 29 或 61 位。只有低三位为 0 时才成立。

【讨论】:

  • 我很确定这是未定义的(或定义的实现,或其他一些“如果您希望代码始终在任何平台上工作,请不要这样做”),因此可能不一定有效。
  • @MatsPetersson 它已定义并将适用于所有 JVM,无论是 32 位还是 64 位。与一些较旧的语言不同,Java 倾向于定义它的所有边缘情况。 ;)
  • 抱歉,我的意思是“这只适用于 Java 以外的其他语言的某些情况下”。
  • @MatsPetersson 这是 C 中未定义的行为。
  • 我认为,JLS3 15.19 可以这样解释。 “就好像右手操作数经过按位逻辑与运算符 & 掩码值为 0x1f。”这使得这是(唯一?)正确答案。
【解决方案4】:
if (x & ((1 << 3)-1) == 0)

或者,如果你真的想使用移位:

if (x == ((x >> 3) << 3))

【讨论】:

    【解决方案5】:

    检查 n 是否能被 9 整除的最简单方法是执行 n%9。 另一种方法是将 n 的数字相加。如果数字之和是 9 的倍数,则 n 是 9 的倍数。 上述方法不是基于位运算符的方法,需要使用“%”和“/”。按位运算符通常比模和除法运算符快。以下是一种基于位运算符的方法来检查是否被 9 整除。

    你应该检查这个链接 http://www.firmcodes.com/check-number-multiple-9-using-bitwise-operators/

    【讨论】:

      【解决方案6】:

      x &lt;&lt; (32-3) == 0intx &lt;&lt; (64-3) == 0Llong

      【讨论】:

      • 两个表达式都会触发 C 中未定义的行为。
      • @ouah 我相信大多数 C 程序都会大量使用未定义的行为。
      【解决方案7】:

      为简单起见

      如果你想知道任何给定的整数 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.
      

      可以在这篇非常好的文章中找到更多信息: Using Bitwise Operators to Work With Colors

      【讨论】:

        【解决方案8】:
        if (((x >> 3) << 3) == x)
            divisibleBy8 = true;
        

        输入 0(零)会失败

        【讨论】:

          【解决方案9】:
          static boolean divisibleBy8(int num) {
              return (number & 7) == 0;
          }
          

          【讨论】:

          • 这不仅仅是使用位移
          • 好吧好吧,不确定“转变”有多么强调。有些人倾向于混淆这些术语。从好的方面来说,它可以工作并且是最快的解决方案。 ;-)
          • “位移”还有什么意思?
          • “按位”实际上是指,只是没有准确表达。
          猜你喜欢
          • 2011-02-28
          • 2011-02-18
          • 1970-01-01
          • 2016-12-06
          • 1970-01-01
          • 1970-01-01
          • 2011-11-05
          相关资源
          最近更新 更多