对 > 32 位整数使用按位运算符

问题描述 投票:0回答:3

我使用按位运算来表示一个整数内的许多访问控制标志。

ADMIN_ACCESS = 1;
EDIT_ACCOUNT_ACCESS = 2;
EDIT_ORDER_ACCESS = 4;

var myAccess = 3; // ie: ( ADMIN_ACCESS | EDIT_ACCOUNT_ACCESS )

if ( myAccess & EDIT_ACCOUNT_ACCESS ) { // check for correct access
   // allow for editing of account

}

其中大部分发生在我项目的 PHP 端。然而,在保存某人的访问级别时,Javascript 用于使用

|
连接多个访问标志。这在某种程度上效果很好。我发现一旦整数(标志)变得太大(> 32 位),它就不再与 Javascript 中的按位运算符一起正常工作。例如:

alert( 4294967296 | 1 ); // equals 1, but should equal 4294967297

我正在尝试为此找到解决方法,这样我就不必将访问控制标志的数量限制为 32。每个访问控制标志是前一个控制标志的两倍,以便每个控制标志不会干扰其他控制标志.

dec(4) = bin(100)
dec(8) = bin(1000)
dec(16) = bin(10000)

我注意到,当将其中两个标志与简单的

+
一起添加时,似乎得到与按位
or
操作相同的答案,但我很难弄清楚这是否是一个简单的替换,或者这样做是否可能出现问题。有人可以评论这个解决方法的有效性吗?示例:

(4294967296 | 262144 | 524288) == (4294967296 + 262144 + 524288)
javascript math bitwise-operators
3个回答
2
投票

只要您确定每个标志都是 2 的幂,并且您不超过 52 位长(由于双精度浮点可以容纳的数量,那么简单地添加标志就可以了,因为这就是 JS 用于数字的方式)。

如果出于某种原因,您需要超过 52 个标志,我建议将标志分组。


2
投票

如果要进行按位运算,则不能超过 32。为了执行按位运算,JavaScript 将数字值(以 8 字节浮点形式保存)转换为 32 位整数,然后对该值执行按位/位移位运算。它将结果整数转换回浮点数,然后再存储到变量中。有关更多信息,请参阅这篇 Moz Dev Net 文章

您仍然可以对浮点数进行整数运算,最多为 9007199254740992,即 2^53。但由于上述原因,您不能使用超过 32 位的按位运算符。

由于 PHP 使用与平台相关的整数,因此您也不能保证 PHP 可以处理超过 32 位的整数。因此,我建议双方将标志分成几组并单独维护。您可以将它们包装在带有访问器的对象中,以确保它们的行为就像一组标志而不是几组。


0
投票

很简单。只需使用除法执行位移即可:

function bitAtPos(mask: number, pos: number): number {
  return mask / 2 ** pos & 1;
}

bitAtPos(18446744073709552000, 64) // 1
© www.soinside.com 2019 - 2024. All rights reserved.