如何检查一个位是否被设置(不使用位运算符)?

7

看一下整数44 - 我需要 Math.CEIL (log(2) 44)个二进制位来表示 44。(答案为6位)

6个二进制位:

___  ___  ___  ___  ___   ___
32   16    8    4    2     1

但是我如何检查(例如)8的位是否已经被检查了呢?

一个简单的解决方案是:

((1<<3) & 44)>0,这将检查位是否已设置。

但请注意,在计算机背后,它会将44转换为其二进制表示,并通过按位操作来检查位是否已设置。

另一种解决方案是,通过使用循环中的toString(2)mod%2来构建二进制。

问题

数学上,通过哪个公式可以测试第n位是否已设置?

(我更喜欢非循环运算而是纯粹的单个数学表达式)


5
从数学的角度来看,是没有勺子的——呃,我的意思是没有比特。 - Jongware
1
@RoyiNamir,但是位运算有什么问题吗?为什么你想要避免它? - Grundy
但是仍然有些混淆概念 - “计算机将44转换为其二进制表示形式,然后通过按位操作检查是否设置了位”不是这样的。这是混淆隐喻(或者可能只是技巧)。 "第n位" 一种按位操作。这就像在大的十进制数字中检查“第n个十进制数”的值(以及任何其他进制)。我非常确定您需要在某个地方使用类似模除法之类的东西。 - Jongware
你为什么不想使用二进制操作呢?这是处理位运算最有效的方式(比使用 toString% 更高效)。或者,你可以使用 log,显然你已经知道了。 - Amadan
我不再有2个二进制选项,而是拥有62个选项。 - Royi Namir
显示剩余2条评论
3个回答

10

将要检查的位的值除以 2,并测试第一位是否设置(可以用 x mod 2 == 1 进行测试)

数学表达式:

floor(value/(2^bitPos)) mod 2 = 1

作为JS函数:

function isSet(value, bitPos) {
   var result =   Math.floor(value / Math.pow(2, bitPos)) % 2;
   return result == 1;
}

注意:bitPos从0开始(表示数字1的位)。

测试第三位 Math.floor((44)/(2^2)) % 2 NaN - Royi Namir
@RoyiNamir,要进行幂运算,请使用 Math.pow,如果我没记错的话,2^22 xor 2 - Grundy
测试用例44返回: isSet(44,5) == true; isSet(44,4) == false; isSet(44,3) == true; isSet(44,2) == true; isSet(44,1) == false; isSet(44,0) == false; - Adam Frederick Wiseman

6

一个值val中,一个索引数字index在基数base下的“位”(实际上是任何进制数),通常可以计算如下:

val = 1966;
index = 2;
base = 10;
alert (Math.floor(val/Math.pow(base,index)) % base);

结果: 9

val = 44;
index = 3;
base = 2;
alert (Math.floor(val/Math.pow(base,index)) % base);

结果:1(这里只可能是01 - 范围总是0..base-1)。

Math.floor(在Javascript中强制转换为整数)和Math.pow的组合有点棘手。即使在整数范围内,Math.pow也可能生成一个略低于预期“整数”的浮点数。也许始终添加一个小常数更安全:

alert (Math.floor(0.1+val/Math.pow(base,index)) % base);

在什么情况下会用到0.1呢?你能提供一个例子吗? - Royi Namir
阅读理解浮点数问题(以及在某个答案中提到的计算机科学家应该了解的浮点算术知识). Javascript不支持"真正的"整数。此外,Math.pow 是一个纯浮点运算,因此可能会出现不准确的情况。(我刚刚测试了一些随机范围,并没有找到一个例子——不过,这可能取决于JS引擎。) - Jongware
1
读了很多遍才提到。但我希望你能提供一个例子来支持那个 0.1 地板辅助工具。 - Royi Namir
@Royi:抱歉,我刚刚测试了基数和指数都为1..35,没有一个符合条件!:) 但是规范对此含糊不清:“...实现依赖的近似值…”顺便说一下,使用0.1的想法是因为epsilon大约在10⁻⁴的数量级。例如,参见C的pow()函数,根据头文件<math.h>,不能正常工作 - Jongware

1
您可以简单地检查位于该位置的bit是否设置为1
function isBitSet(no, index) {
    var bin = no.toString(2);
    // Convert to Binary

    index = bin.length - index;
    // Reverse the index, start from right to left

    return bin[index] == 1;
}
isBitSet(44, 2); // Check if second bit is set from left

DEMO

可以直接翻译为:

{{链接1:DEMO}}

。其中,“link1”和“链接1”都是表示一个链接的标识符,而“DEMO”则是链接的文本内容,保留了HTML标记。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接