Phix
Phix

Reputation: 9920

Javascript bit masks

I've used bit masks in Java (not Javascript) before, but it's been a while and it's making me bug out.

This is the Typescript I'm wanting to work with. Theres 3 roles,

enum Type {
    FRUIT = 0x1,
    VEGGIE = 0x2,
    BOTH = FRUIT | VEGGIE
}

class Thing {
    role:number;

    constructor(role:Type){
        this.role = role;
    }
    getRole(){
        return this.role;
    }
    is(role:Type) {
        return !!(this.role & role);
    }
}

var whatever = new Thing(Type.FRUIT);

console.log('fruit', whatever.is(Type.FRUIT));
console.log('veggie', whatever.is(Type.VEGGIE));
console.log('both', whatever.is(Type.BOTH));

// fruit true
// veggie false
// both true

I conceptually see why "both" is coming back as "true", but my bit math isn't great.

When the role is either FRUIT or VEGGIE, the others are false. When it's set to BOTH, all should be true.

Tried a few combinations of shifts and bit operations, but I can't get that output. If I try them separate it's fine, but I'd like to use combinations of bits to build.

Upvotes: 1

Views: 6777

Answers (2)

Fenton
Fenton

Reputation: 251262

When you perform a bitwise & operation the result is that the bits turned on in both values used in the expression.

For example (taken from Pro TypeScript, p 207)

a 1011
&
b 1101
= 1001

The first column, both values are "switched on (1)", so the result is also switched on. The second column, a is switched off, so the result is 0, the third column b is off, so again a 0 and finally the last column both are on, so a 1.

In your case, it is even simpler because you are dealing with such small numbers...

a 01 // FRUIT
&
b 11 // ALL
= 01 // FRUIT

So the result is 01, or 1 if you have ten fingers.

If you use a double-bang !! to convert 1 to to a boolean (I call this slacker parsing), you'll get true because 1 is truth-y. This doesn't answer the question you were really asking, which is "does this bit flag match".

This is why this.role & role === role is the correct code, because you won't get a mistake from the "truthiness" of the value 1.

Upvotes: 7

Qwertiy
Qwertiy

Reputation: 21518

return !!(this.role & role);

Your version works as isAny, but you want it to work as isAll:

return (this.role & role) === role;

Upvotes: 6

Related Questions