我有一组十进制数字。我需要检查它们中的每一个是否设置了特定位。如果设置了该位,我需要返回 1,否则返回 0。
我正在寻找一种简单快速的方法来做到这一点。
比如说,我正在检查是否设置了第三位。我可以做 (number AND (2^2)),如果设置了该位,它将返回 4,否则将返回 0。如何使它返回 1 而不是 4?
谢谢!
5 回答
虽然除法解决方案很简单,但我认为位移操作会更有效。不过,您必须对其进行测试才能确定。例如,如果您使用基于 1 的位索引,您可以这样做:
Dim oneOrZero As Integer = (k And 2 ^ (n - 1)) >> (n - 1)
(其中 k 是数字,n 是位索引)。当然,如果您使用基于 0 的位索引,您可以这样做:
Dim oneOrZero As Integer = (k And 2 ^ n) >> n
if ((number AND (2^bitnumber) <> 0) then return 1 else return 0 end if
如果您可以将返回类型更改为布尔值,那么这会更优雅
return ((number AND (2^bitnumber)) <> 0)
对不起,伙计们,我今天太慢了。
测试十进制数“k”中的位数“n”:
(k AND 2^(n-1))/(2^(n-1))
如果该位已设置,则返回 1,否则返回 0 .
================================================== ====
再次嗨,伙计们!
我将三个提议的解决方案的性能与从零开始的索引进行了比较,结果如下:
“位移解决方案” - 8.31 秒
“如果...那么解决方案” - 8.44 秒
“除法解决方案” - 9.41
秒是连续四次运行的平均值。
令我惊讶的是,第二个解决方案优于第三个解决方案。
但是,在我以这种方式修改“除法解决方案”之后:
p = 2 ^ n : oneOrZero = (k And p) / p
它在 7.48 秒内开始运行。
因此,这是提议的解决方案中最快的(尽管 Keith 说 :-)。
感谢大家的帮助!
是的!只需使用位掩码。我枚举位,然后将数字与位值相加。PC 端的数学很少,因为它使用查找表。AND 基本上会关闭除您感兴趣的位之外的所有其他位。然后您将其与自身进行检查以查看它是否处于打开/关闭状态。
Enum validate
bit1 = 1
bit2 = 2
bit3 = 4
bit4 = 8
bit5 = 16
bit6 = 32
bit7 = 64
bit8 = 128
End Enum
If num And validate.bit3 = validate.bit3 Then true
我真的不知道它是否可以帮助比上述更多的人,但是,我们开始吧。
当我需要快速检查数字时,我会直接比较该位的十进制值。
我的意思是,如果我需要查看第 6 位是否为 (32),我会检查它的十进制值,如下所示:
if x and 32 = 32 then "the bit is ON"
例如,尝试用 32、4 和 2... 以及其他位检查 38。您只会看到实际打开的位。
我希望它可以帮助。