最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

How to use bitmasks to store boolean values in JavaScript - Stack Overflow

programmeradmin1浏览0评论

I'm a bit confused after reading about how to use bitmasks to store boolean values. I would like to have a set of boolean values and then generate a unique integer for each bination of the values. Here is the current system so far:

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
}

But the problem is, I am not sure if I am supposed to handle the "not" case, along the lines of this:

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
}

All I know is that I've seen |, &, and ^ related to bitmasks, and I know to find if a boolean is in the bitmask you do var yes = value & b, but I'm just confused how to generate the bitmask so that it handles both the if (true) and if (false) cases. Not sure if I'm supposed to be using ^ somewhere, or what else I'm doing wrong. Please advise. Thank you!

I'm a bit confused after reading about how to use bitmasks to store boolean values. I would like to have a set of boolean values and then generate a unique integer for each bination of the values. Here is the current system so far:

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
}

But the problem is, I am not sure if I am supposed to handle the "not" case, along the lines of this:

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
}

All I know is that I've seen |, &, and ^ related to bitmasks, and I know to find if a boolean is in the bitmask you do var yes = value & b, but I'm just confused how to generate the bitmask so that it handles both the if (true) and if (false) cases. Not sure if I'm supposed to be using ^ somewhere, or what else I'm doing wrong. Please advise. Thank you!

Share Improve this question asked Dec 20, 2017 at 21:25 Lance PollardLance Pollard 79.5k98 gold badges330 silver badges607 bronze badges 1
  • Can you be more specific on what you mean with the "not" case? Wouldn't that just be the negated form of "yes"? I also wonder what brings you into using the bitwise xor operator there. – E_net4 Commented Dec 20, 2017 at 21:42
Add a ment  | 

3 Answers 3

Reset to default 7

I am not sure if I am supposed to handle the "not" case

You're not supposed to handle it at all. A bitmask works so that you either have a bit with value 1 if your flag is set or the bit with value 0 if not. Given that your value starts with 0s everywhere (the integer 0), you just have to set the bit (by OR 1) when your condition is true and you don't have to do anything otherwise.

You could simplify your code to

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
}

A NOT op will invert the bit so it needs to be set in order to be cleared.

(Assuming you want to toggle bits on or off on an existing value:) You can use NOT together with a AND mask to clear off a bit like this:

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));

You can of course also check if the bit is set and then NOT it if it is:

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");

To set it instead, you would use OR regardless of the state:

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

If you need to clear several bits at once you can first OR the bits together, then use that with NOT for a AND mask:

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));

So in the function you could so something like this:

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));

By doing var value=1 at the beginning you are already setting value to 2, because 1<<1=2. I suggest you set value=0, and remove else value = value ^ c, since that operation does not cause any change when you start with all zeros. Your code would look as follows:

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

This prints out 4, instead of 6 for uniqueint1.

发布评论

评论列表(0)

  1. 暂无评论