检查整数中是不是只设置了一个位(无论其位置如何)
Posted
技术标签:
【中文标题】检查整数中是不是只设置了一个位(无论其位置如何)【英文标题】:Check if only one single bit is set within an integer (whatever its position)检查整数中是否只设置了一个位(无论其位置如何) 【发布时间】:2012-11-16 16:10:00 【问题描述】:我使用 64 位整数中的位存储标志。 我想知道在 64 位整数中的位置是否设置了一个位(即我不关心任何特定位的位置)。
boolean isOneSingleBitSet (long integer64)
return ....;
我可以使用Bit Twiddling Hacks (by Sean Eron Anderson) 计算位数,但我想知道仅检测是否设置了一个位的最有效方法是什么...
我发现了一些其他相关的问题:
(8051) Check if a single bit is set Detecting single one-bit streams within an integer还有一些***页面:
Find first one Bit manipulation Hamming weight注意:我的应用程序是用 java 编写的,但我对使用其他语言的优化感到好奇...
编辑:Lưu Vĩnh Phúc 指出我的问题中的第一个链接已经得到了答案:请参阅 Bit Twiddling Hacks 中的 Determining if an integer is a power of 2 部分(作者 Sean Eron安德森)。我没有意识到一位与二的幂是一样的。
【问题讨论】:
对于 Java,我会考虑为此目的使用 BitSet 类,它支持方便的 isEmpty() 方法以及许多其他使位标志更易于使用的方法。 它已经在上面链接的 Bit Twiddling Hacks 中:Determining if an integer is a power of 2 哦!谢谢 :-) 我更新了我的问题 :-) 干杯 这能回答你的问题吗? How to check if a number is a power of 2 【参考方案1】:如果您只是想检查是否设置了一个位,那么您实际上是在检查该数字是否是 2 的幂。要做到这一点,您可以这样做:
if ((number & (number-1)) == 0) ...
这也将 0 视为 2 的幂,因此如果这很重要,您应该检查数字是否不是 0。那么:
if (number != 0 && (number & (number-1)) == 0) ...
【讨论】:
对不起,我已经测试了你的答案,我有这些结果:0
->false
(ok) ; 1
->true
(ok) ; 2
->false
(KO) ; 3
->false
(ok) ; 4
->false
(KO) 5
->false
(ok) ...请你也检查一下吗?
看看第二个版本,我已经详细说明了检查 != 0 的效果。就我所见,真的很好。
感谢您的编辑,但您的第一行 if ((number & (number-1)) == 0) ...
不检查 number
是否为 2 的幂,正如您在我的测试结果中看到的那样(请参阅我之前的评论)。要检查 number
是否是 2 的幂,您可以执行以下操作:if (number && !(number & (number - 1)) ...
(请在您的回答中接受我的编辑)
不是在 Java 中你不能。在 C 中,你写的那行基本上和我写的一样。如果您想要与 C 而不是 Java 相关的答案,请相应地修改并重新标记您的问题。
好的,虽然我确实口头说过你需要进行零检查:你真的无法将其转化为代码吗??【参考方案2】:
(使用 x 作为参数)
检测是否设置了至少一位很容易:
return x!=0;
同样检测第一个位(第二个最低位)是否设置很容易:
return (x&2)!=0;
如果它是 2 的幂,则恰好设置了一位。这有效:
return x!=0 && (x & (x-1))==0;
【讨论】:
有什么方法可以检查哪个位在吗? (在日志旁边)顺便说一句很棒的技巧 @hl3mukkel 您可以使用迭代除法(这只是一种计算整数对数的方法)。如果您正在寻找更快的东西,请查看***.com/q/14429661/499214。使用对数肯定更具可读性,但会出现舍入问题。 谢谢!我发现link 是一种高效且干净的方法。【参考方案3】:包装类java.lang.Long
有一个静态函数bitCount()
,它返回long(64位int)中的位数:
boolean isSingleBitSet(long l)
return Long.bitCount(l) == 1;
请注意,int 在 java 中是 32 位的。
【讨论】:
将条件更改为 ==1,这将起作用,但严格来说,它几乎肯定不是检测单个位的最有效方法。 你知道这个方法的开销吗?这当然是最易读的解决方案,即使不是最快的。 现在 (>0
),这将检查数字是否非零(感谢 @NeilCoffey 的注意)。
+1 对于这个可读的解决方案。有没有检查整数是否是2的幂的函数?
Jan - 我猜,仅从操作的数量来看,它基本上会比我在回答中提到的通常方法慢几倍。至于可读性,你可以将任何你想要的实现包装在一个名为 isSingleBitSet() 的方法中——我不确定从这个角度来看它有什么不同......【参考方案4】:
让我们假设 X 是一个 64 位的全 0,除了你要找的那个;
return ((64bitinteger&X)==X)
【讨论】:
64bitinteger = 0
时返回 true :-(
您的答案中的X
是什么?同64bitinteger
?
1010101 如果要检查第 3 位是否为 1 1010101 & 0010000 在此示例中等于 0010000 X=0010000
感谢您的回答,但我正在寻找最有效的方法来了解是否在任何位置设置了单个位...【参考方案5】:
假设您已经有ffs()
的高效(或硬件)实现 - 找到第一个集合 - 您可以执行以下操作:
bool isOneSingleBitSet (long integer64)
return (integer64 >> ffs(integer64)) == 0;
ffs()
功能可能已经可用,或者您可能想查看your own link above
【讨论】:
ffs()
在 java 中可用吗?
+1 你的答案是有效的 :-) 但使用 GCC __builtin_ffs()
进行了测试。请告诉我ffs()
在 java 中是否可用...
我不是java开发者!只是对您的问题感兴趣【参考方案6】:
似乎您可以对要检查的单个位的long
表示进行按位与运算。例如,检查 LSB
return( (integer64 & 1L)!=0 );
或者检查右数第四位
return( (integer64 & 8L)!=0 );
【讨论】:
好的...但是您如何检查是否设置了一个位?你检查每个 64 位吗? 使用这个答案中的方法,是的,但我不推荐它。我将最初的问题理解为检查特定位,而不是按预期检查任何单个位。正如您所想,这个问题更有趣,Neil Coffey 和 Jan Dvorak 回答得很好。 感谢@Pursuit。我会改进一下我的问题以便更容易理解;-)以上是关于检查整数中是不是只设置了一个位(无论其位置如何)的主要内容,如果未能解决你的问题,请参考以下文章
在检查指定位置是不是设置位时,右移数字和左移位掩码哪个更好?