【问题标题】:Bit manipulation in a range范围内的位操作
【发布时间】:2017-03-04 02:30:03
【问题描述】:

虽然我知道在特定位置设置/取消设置的过程 - 在一定范围内(例如从位置 x 到 y)执行此操作的最有效方法是什么?

101011011011

n=12
x=3,y=7(from right)

Bit set: 101011111111
Bit unset: 101010000011

必须动态推送掩码,因为 x 和 y 显然是随机的。
感谢您的帮助。

【问题讨论】:

  • 位设置超出范围 - 使用 or 和掩码。位清除超出范围使用 and 和掩码。通常,计算机可以在 1 次操作中完成整个范围。

标签: bit-manipulation bit


【解决方案1】:

我们是在谈论类似 C 的操作吗?如果你想让xy 成为变量,你可以构建两个掩码:

unsigned set(unsigned val, int x, int y) {
  unsigned hi = ~0 << x;    // 1's at position x and higher
  unsigned lo = ~(~0 << y); // 1's at positions lower than y
  return val | (lo & hi);
}

unsigned clear(unsigned val, int x, int y) {
  unsigned hi = ~(~0 << x);   
  unsigned lo = ~0 << y; 
  return val & (lo | hi);
}

请注意,范围的末尾不包括高端。所以set(foo, 5, 9) 设置位 5 到 8,其中每个位 i 是具有值 2^i 的位。

【讨论】:

  • 这是正确的吗?从示例 - 它似乎也设置了 x 和 y 范围之外的位
  • @IUnknown 谢谢。我最后的操作错了。现已修复。
【解决方案2】:

跟进 设置从 3 到 7:

value = 1010110...
mask = 0x7C; // 0111 1100 binary
value |= mask;

清除

value = 1010110...
mask = 0x7C; // 0111 1100 binary
value &= ~mask;

在 where | 上面使用 C 风格是或,& 是和,~ 是恭维。

【讨论】:

  • 请检查上面的编辑 - 可能一开始并不清楚
【解决方案3】:

如果你像往常一样从 0 开始计数,你可以使用:

unsigned set(unsigned x, unsigned l, unsigned h) {
    return x | (((1u << h) << 1) - (1u << l));
}

unsigned reset(unsigned x, unsigned l, unsigned h) {
    return x & ~(((1u << h) << 1) - (1u << l));
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-09
    • 1970-01-01
    • 2021-01-14
    • 1970-01-01
    • 2011-09-08
    相关资源
    最近更新 更多