【问题标题】:Javascript bit masksJavascript 位掩码
【发布时间】:2015-09-04 21:35:33
【问题描述】:

我以前在 Java(不是 Javascript)中使用过位掩码,但已经有一段时间了,这让我很困惑。

这是我想要使用的 Typescript。有3个角色,

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

我从概念上理解为什么“两者”会返回“真实”,但我的数学并不好。

当角色为FRUIT或VEGGIE时,其他为假。当它设置为BOTH 时,一切都应该为真。

尝试了一些移位和位操作的组合,但我无法获得该输出。如果我尝试将它们分开,那很好,但我想使用位组合来构建。

【问题讨论】:

  • 只需引入一个带有isFruit 和其他标志的新类Type。当你应该使用位掩码和位算术时,JS 不是语言。
  • @zerkms 为什么不鼓励 JavaScript 中的按位运算?我已经多次使用它并取得了巨大的成功——您只需要注意在 JS 中按位运算仅限于 32 位整数。
  • @dave 有什么理由更喜欢位算术而不是 JS 中的布尔标志?解决方案过于复杂的技术原因是什么?
  • 您的问题到底是什么?代码对我来说很好
  • @zerkms 如果是两个或三个静态 fag,那么布尔值就可以了。如果您要处理大量标志,那么合并到一个属性中很方便。它们还使您可以灵活地添加新标志,而无需更改数据结构。

标签: javascript typescript bit-manipulation bitmask


【解决方案1】:

当您执行按位& 操作时,结果是表达式中使用的两个值中的位都打开。

例如(取自Pro TypeScript,第 207 页)

a 1011
&
b 1101
= 1001

第一列,两个值都是“开启(1)”,所以结果也是开启的。第二列 a 关闭,所以结果是 0,第三列 b 关闭,所以再次 0 和最后一列都打开,所以 1。

在您的情况下,它甚至更简单,因为您正在处理如此小的数字......

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

所以结果是01,如果你有十根手指,则结果是1。

如果您使用双键!! 将1 转换为布尔值(我称之为slacker parsing),您将得到true,因为1 是真值。这并不能回答您真正要问的问题,即“此位标志是否匹配”。

这就是为什么this.role & role === role 是正确代码的原因,因为您不会从值1 的“真实性”中得到错误。

【讨论】:

    【解决方案2】:
    return !!(this.role & role);
    

    您的版本以isAny 工作,但您希望它以isAll 工作:

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

    【讨论】:

    • 虽然这个答案实际上可能包含正确的代码,但它确实需要一点解释。
    猜你喜欢
    • 1970-01-01
    • 2017-01-17
    • 1970-01-01
    • 1970-01-01
    • 2018-04-28
    • 1970-01-01
    • 1970-01-01
    • 2020-01-28
    相关资源
    最近更新 更多