【问题标题】:Unset the rightmost set bit [duplicate]取消设置最右边的设置位[重复]
【发布时间】:2011-06-09 21:23:44
【问题描述】:

可能的重复:
How do you set, clear and toggle a single bit in C?
Removing lowest order bit

n 是一个正整数。它的最右边的设置位如何取消?

n= 7 => n = 0111。 我想要0110 作为输出。是否有任何简单的按位破解来实现目标?

【问题讨论】:

标签: c++ c algorithm math bit-manipulation


【解决方案1】:

尝试n & (n-1),其中&bitwise AND

n = 7
n - 1 =6

n & (n-1)=> 0 1 1 1   (7)
          & 0 1 1 0   (6)
           --------- 
            0 1 1 0  (done!)

EDIT(回应Forest给出的评论)

n = 6 
n - 1 = 5

n & (n-1)=> 0 1 1 0   (6)
          & 0 1 0 1   (5)
           --------- 
            0 1 0 0  (done!)

【讨论】:

  • @taspeotis :再次检查问题“如何取消其最右边的 set 位?”
  • 啊,是的。我忽略了“设置”这个词。
  • +1 不错!我还是不明白人们怎么这么快就看到了这样的解决方案。
  • @Toolbox:要么我们以前见过它们,要么我们在童年时代发明了它们。对我来说,两者兼而有之。
  • @Toolbox 见 Hacker's Delight(书)
【解决方案2】:
unsigned int clr_rm_set_bit(unsigned int n)
{
    unsigned int mask = 1;
    while(n & mask) {
        mask <<= 1;
    }
    return n & ~mask;
}

【讨论】:

  • 这是 O(N) 而 Prasoon 是 O(1)。此外,您想要更像while(!(n &amp; mask)) 的东西,但即使这样也不适用于n = 0
  • 其实这个方法(正确实现时)不是O(n)。这是O(log(n))。由于 n 受 unsigned int 大小的限制,因此您也可以将其称为 O(1)。
  • 对,应该检查 n==0 和 n
【解决方案3】:

你的问题不清楚。

如果您只想取消设置位 0,这里有一些方法(根据您所涉及的类型,行为会略有不同):

x &= -2;
x &= ~1;
x -= (x&1);

如果您想取消设置已设置的位中的最低位,这里有一些方法:

x &= x-1;
x -= (x&-x);

注意x&amp;-x 等于x 的最低位,至少当x 是无符号或二进制补码时。如果你想做这样的位运算,你应该只使用无符号类型,因为有符号类型在按位运算下具有实现定义的行为。

【讨论】:

  • “最右边的设置位”似乎非常清楚。这只是一个选择不当的例子。
猜你喜欢
  • 2021-04-25
  • 2021-01-08
  • 1970-01-01
  • 2014-05-11
  • 1970-01-01
  • 2016-02-05
  • 2015-10-02
  • 2014-03-25
  • 2013-06-18
相关资源
最近更新 更多