【问题标题】:Given a mask size, efficiently create a mask with the low bits set给定一个掩码大小,有效地创建一个设置了低位的掩码
【发布时间】:2016-11-23 22:34:43
【问题描述】:

鉴于大小为size 的掩码的大小,我想创建一个long mask,掩码集的底部为size,高位为零。例如,size == 4 的掩码是0b1111(又名0x0000000000000000F),依此类推。 size 必须在 0 <= size <= 64 范围内。

对于所有输入都不正确的典型尝试如下:

long makeMask(int size) {
  return (1L << size) - 1;
}

...但这对于 size == 64 失败,返回 0 而不是预期的全一:0xFFFFFF....。对于int 掩码,我可以转换为long 以避免此问题,但对于long,我没有看到类似的解决方法。

我可以这样做:

long makeMask(int size) {
  return size == 64 ? -1L : (1L << size) - 1;
}

...但我真的很想避免那里出现不可预测的分支。

【问题讨论】:

  • 也许您可以尝试将这个C++ answer 转换为Java?
  • 总会有边界问题。在您的 64 岁和@LukeLee 的零号之间进行选择。或者制作一个查找表。
  • @ToddSewell - 对,但两种解决方案都归结为我上面的条件(或条件移动,如条件的减少,例如,-(size != 0) &amp; ...
  • @EJP - 当然不会有总是有边界问题 - 上面的条件没有边界问题。如果您的意思是如果没有查找表就无法有效且正确地实施-我想这还有待观察。我的经验是,通常可以通过一两条额外的指令来实现的。
  • 在纯位移实现中总会存在边界问题,您必须使用条件分支或查找表来解决。我没有说过效率,或者查找表是唯一的另一种可能性:不要把话放在我的嘴里。您需要决定是否需要避开分支。您现在已经声明了两者。

标签: java optimization bit-manipulation


【解决方案1】:

您可以使用第 7 位的倒数并将其移位:

long x = (size >> 6) ^ 1;
return (x << size) - 1;

size = 64 这设置x = 0(0 &lt;&lt; whatever) - 1 显然是-1。

在其他情况下,它简化为旧的(1L &lt;&lt; size) - 1

【讨论】:

  • 这真是令人印象深刻!
  • 我还没有找到更好的,所以接受这个。
猜你喜欢
  • 2018-02-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-02-03
相关资源
最近更新 更多