如何使用bitmasks在JavaScript中存储布尔值

时间:2017-12-20 21:25:41

标签: javascript bitmask

在阅读有关如何使用位掩码存储布尔值后,我有点困惑。我想有一组布尔值,然后为每个值组合生成一个唯一的整数。以下是目前的系统:

var a = 1 << 1
var b = 1 << 2
var c = 1 << 3
var d = 1 << 4

var uniqueint1 = getInt(true, false, false)
var uniqueint2 = getInt(true, true, false)
var uniqueint3 = getInt(true, true, true)
// ...

function getInt(x, y, z) {
  var value = a
  if (x) value = value | b
  if (y) value = value | c
  if (z) value = value | d
  return value
}

但问题是,我不确定我是否应该处理&#34;而不是&#34;案例,按照以下方式:

function getInt(x, y, z) {
  var value = a
  if (x) value = value | b
  else value = value ^ b

  if (y) value = value | c
  else value = value ^ c

  if (z) value = value | d
  else value = value ^ z

  return value
}

我所知道的是,我已经看到与位掩码相关的|&^,而且我知道要查找布局是否在您使用的位掩码中var yes = value & b,但我只是混淆了如何生成位掩码,以便它处理if(true)和if(false)情况。不确定我是否应该在某个地方使用^,或者我做错了什么。请指教。谢谢!

3 个答案:

答案 0 :(得分:5)

  

我不确定我是否应该处理“不”案件

你根本不应该处理它。位掩码的工作原理是,如果设置了标志,则要么值为1,要么值为0的位为0。鉴于您的值始于function getInt(x, y, z) { return (0b10 // a | (x << 2) // 0b00100 if x and 0b00000 else | (y << 3) // 0b01000 if y and 0b00000 else | (z << 4)); // 0b10000 if z and 0b00000 else } s无处不在(整数0),您只需在条件为真时设置该位(按OR 1),否则您不必执行任何操作。

您可以将代码简化为

Definition

答案 1 :(得分:1)

NOT op将反转该位,因此需要设置它才能被清除。

(假设您要在现有值上打开或关闭位:)您可以将NOT与AND掩码一起使用以清除这样的位:

&#13;
&#13;
var v = 0xff;            // value
var bit3 = 1<<3;         // the bit we want to clear

// clear bit 3:
v &= ~bit3;              // create a AND mask inverting bit 3 and AND with value
console.log(v.toString(2));

v &= ~bit3;              // will not set the bit even when already cleared
console.log(v.toString(2));
&#13;
&#13;
&#13;

您当然也可以检查该位是否已设置,然后检查是否为:

&#13;
&#13;
var v = 0xff;
var bit3 = 1<<3;

if (v & bit3) v ^= bit3;   // NOT bit 3 if set
console.log(v.toString(2));

// should not trigger:
if (v & bit3) console.log("Whaa");
&#13;
&#13;
&#13;

要改为设置它,无论状态如何都使用OR:

if (v & bit3) v ^= bit3;   // NOT bit 3 if set
else {v |= bit3};          // set it not set already

如果你需要一次清除几个位,你可以先将这些位组合在一起, 然后使用NOT和AND掩码:

&#13;
&#13;
var v = 0xff;
var bit1 = 1<<1;
var bit3 = 1<<3;

// create NOT mask:
var mask = bit1 | bit3;

// clear bits:
v &= ~mask;
console.log(v.toString(2));
&#13;
&#13;
&#13;

所以在函数中你可以这样:

&#13;
&#13;
var a = 0xff;
var b = 1 << 2
var c = 1 << 3
var d = 1 << 4

function getInt(x, y, z) {
  var value = a;
  value = x ? value | b : value & ~b;
  value = y ? value | c : value & ~c;
  value = z ? value | d : value & ~d;
  return value
}

// turn off bit c/d (bit index 3 & 4):
console.log(getInt(true,false,false).toString(2));

// turn on c, off b/d
console.log(getInt(false,true,false).toString(2));

// with same value turn off all, then on c:
a = getInt(false, false, false);
console.log(getInt(false,true,false).toString(2));
&#13;
&#13;
&#13;

答案 2 :(得分:0)

通过在开头执行var value=1,您已将值设置为2,因为1<<1=2。我建议您设置value=0,然后删除else value = value ^ c,因为当您以全零开头时,该操作不会导致任何更改。您的代码如下所示:

var a = 1 << 1
var b = 1 << 2
var c = 1 << 3
var d = 1 << 4

function getInt(x, y, z) {
  var value = 0
  if (x) value = value | b
  if (y) value = value | c
  if (z) value = value | d
  return value
}

var uniqueint1 = getInt(true, false, false)
var uniqueint2 = getInt(true, true, false)
var uniqueint3 = getInt(true, true, true)
uniqueint1

这会为4打印6而不是uniqueint1