2015-09-04 2 views
1

Раньше я использовал бит-маски в Java (а не Javascript), но это было какое-то время, и это заставляет меня ошибиться.Javascript бит маски

Это машинопись, с которой я хочу работать. Theres 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, все должно быть правдой.

Пробовал несколько комбинаций сдвигов и бит операций, но я не могу получить этот вывод. Если я попробую их разделить, это прекрасно, но я бы хотел использовать комбинации битов для сборки.

+0

Просто введите новый класс 'Type' с' isFruit' и другими флагами. JS не является языком, когда вы должны использовать битмаски и битовую арифметику. – zerkms

+0

@zerkms Почему вы отвлекаете поразрядную арифметику в JavaScript? Я использовал его несколько раз с большим успехом - вам просто нужно знать, что побитовые операции ограничены 32-битными целыми числами в JS. – dave

+0

@dave любая причина предпочитать битовую арифметику поверх только булевых флагов в JS? Какова техническая причина чрезмерного усложнения решения? – zerkms

ответ

3
return !!(this.role & role); 

Ваша версия работает как isAny, но вы хотите, чтобы работать как isAll:

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

Хотя этот ответ может содержать правильный код, ему действительно нужно немного объяснения. – dave

+0

@Phix, ответ обновлен. – Qwertiy

+0

Сладкий, спасибо. – Phix

4

При выполнении побитового & операции результата является то, что биты включены в оба значения, используемые в выражении.

Например (взято из 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.

Смежные вопросы