【问题标题】:How can I tell if a number is a multiple of four using only the logic operator AND?如何仅使用逻辑运算符 AND 判断一个数字是否是四的倍数?
【发布时间】:2010-10-19 10:04:00
【问题描述】:

我正在搞乱汇编语言编程,我很好奇如何使用逻辑运算符 AND 判断一个数字是否是 4 的倍数?

我知道如何使用“div”或“remainder”指令来做到这一点,但我正在尝试通过数字/单词的位操作来做到这一点。

谁能指出我正确的方向?我正在使用 MIP,但与语言无关的答案很好。

【问题讨论】:

    标签: assembly binary bit-manipulation


    【解决方案1】:

    好吧,要检测一个数字是否是另一个数字的倍数,您只需执行x MOD y。如果结果为0,则为偶数。

    对于每个y2 的幂,(x MOD y) 也等于(x AND (y - 1))

    因此:

    IF (x AND 3) == 0 THEN
        /* multiple of 4 */
    

    编辑:

    好的,你想知道为什么 (x MOD y) == (x AND (y - 1)) y 是 2 的幂。我会尽力解释。

    基本上,如果一个数字是 2 的幂,那么它只有一个位集(因为二进制是以 2 为底的)。这意味着所有低位都未设置。比如:16 == 10000b, 8 == 1000b

    如果从这些值中减去 1。您最终会设置未设置的位,并设置其下方的所有位。

    15 = 01111b, 7 = 0111b 等。所以基本上它是创建一个掩码,可用于测试是否设置了任何低位。我希望这很清楚。

    编辑: Bastien Léonard 的评论也很好地涵盖了它:

    如果你将(无符号)除以 4,你 右移两位。就这样 余数是那两位,得到 分开时丢失。 4 - 1 = 11b, 也就是说,一个产生两个的掩码 当您将其与 价值。

    编辑:请参阅此页面以获得更清晰的解释:http://en.wikipedia.org/wiki/Power_of_two#Fast_algorithm_to_check_if_a_positive_number_is_a_power_of_two

    它涵盖了检测 2 的幂,如果它是 2 的幂,则使用 AND 作为快速模运算。

    【讨论】:

    • 是的,我在解释为​​什么你可以用 y -1 AND 来获得与 MOD y 相同的值。
    • @tvanfosson:感谢您的回滚,在您在另一篇文章中发表评论后,我正准备这样做:)。
    • @Evan Teran,我明白你怎么说它们是等价的,但我仍然不明白为什么会是 y - 1?
    • @Mithrax:如果将(无符号)除以 4,则向右移动两位。因此,剩下的就是这两个位,当你除法时它们会丢失。 4 - 1 = 11b,即一个掩码,当您将其与一个值进行“与”运算时会产生最右边的两个位。
    • @Bastien:很好的措辞,添加到我的答案中。
    【解决方案2】:

    (x & 3) == 0

    W.r.t.汇编语言,如果可用则使用 TST,否则使用 AND,并检查零标志。

    【讨论】:

    【解决方案3】:

    在 x86 汇编中:

        test eax, 3
        jnz not_multiple_of_4
    
        ; action to be taken if EAX is a multiple of 4
    
    not_multiple_of_4:
        ; ...
    

    【讨论】:

      【解决方案4】:

      如果一个数字的低 2 位为 0,则该数字是 4 的倍数,因此您只需将该数字右移两次并检查移位的位是否为 0。

      【讨论】:

      • 大多数机器只跟踪移出的最后一位,或者 OP 询问的 MIPS 根本没有标志。如果您想使用移位,您将 left 移位 32-2 以移出所有 other 位,只留下可能不是的低 2 位零。或者更好的是,使用 AND 将它们隔离,例如 x & 3
      猜你喜欢
      • 2012-04-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-12
      相关资源
      最近更新 更多