Побитовые операторы перестают работать после 2^31

Скажем, у меня есть это:

// different things you can do
var CAN_EAT = 1,
    CAN_SLEEP = 2,
    CAN_PLAY = 4,
    CAN_DANCE = 8,
    CAN_SWIM = 16,
    CAN_RUN = 32,
    CAN_JUMP = 64,
    CAN_FLY = 128,
    CAN_KILL = 256,
    CAN_BE_JESUS = Math.pow(2, 70);

// the permissions that I have
var MY_PERMS = CAN_EAT | CAN_SLEEP | CAN_PLAY | CAN_BE_JESUS;

// can I eat?
if(MY_PERMS & CAN_EAT) alert('You can eat!'); /* RUNS */

// can I sleep?
if(MY_PERMS & CAN_SLEEP) alert('You can sleep!'); /* RUNS */

// can I play?
if(MY_PERMS & CAN_PLAY) alert('You can play!'); /* RUNS */

// can I be jesus?
if(MY_PERMS & CAN_BE_JESUS) alert('You can be jesus!'); /* WONT RUN */

Затем, если я запущу его, он напечатает, что я могу есть, спать и играть. Он не напечатает, что я могу быть Иисусом, потому что это число 2^70. Если я сделаю число 2 ^ 31, тогда это сработает (я на 64-битной машине, но должен запускать Chrome в 32-битном режиме, когда я запускал приведенный выше пример).

Я постоянно сталкиваюсь с этой проблемой в PHP, когда имею дело с побитовыми операторами. Часто я могу работать со сценарием, в котором я нахожусь, поэтому наличие максимум 31 или 63 вещей в моем списке не имеет большого значения, но иногда мне нужно иметь гораздо больше. Есть ли способ обойти это ограничение? Побитовые операторы такие быстрые и удобные.


person David Zorychta    schedule 08.04.2012    source источник
comment
Язык? Вы говорите, PHP... тоже.   -  person Aaron D. Marasco    schedule 08.04.2012
comment
Мои извинения, приведенный выше пример — это JavaScript.   -  person David Zorychta    schedule 08.04.2012


Ответы (2)


Ну, проблема с этим, по-видимому, как вы и подозревали, в ширине целого числа в javascript. Согласно это, числа в js могут доходить до 2^53, поэтому у вас может быть 53 разных бита. Согласно этому, на 64-битных машинах php полностью на 2^63 - 1, так что вы получите 62 бита.
Если вам нужно больше, вы должны переосмыслить свой дизайн - не могли бы вы разделить флаги на 2 (или более) группы, где каждая группа имеет свое значение (например, действия, связанные с едой, другие действия, что-либо еще и т. д.)?

person Eran Zimmerman Gonen    schedule 12.04.2012

Подробнее об этом можно прочитать в Спецификации языка ECMAScript, ECMAScript — это подмножество JavaScript, см. здесь и здесь.

` Some ECMAScript operators deal only with integers in the range -2^31
through 2^31 - 1, inclusive, or in the range 0 through 2^32-1, inclusive. 
These operators accept any value of the Number type but first convert 
each such value to one of 2^32 integer values. 
See the descriptions of the ToInt32 and ToUint32 operators in 9.5 and 
9.6, respectively. `
person Emil A.    schedule 30.01.2014