Как я могу заставить этот побитовый код работать? - PullRequest
1 голос
/ 17 сентября 2011

побитовые операторы работают только с целыми числами в PHP, а максимальный размер целого числа составляет 2 ^ 63 на 64-битных серверах.Если я создаю значение, большее, чем это, он преобразует мою переменную в число с плавающей точкой, и побитовые операторы перестают функционировать.У меня есть следующий пример:

<?php

$CAN_DANCE = 2;

$CAN_SING = 4;

$CAN_PLAY = 8;

$CAN_BEGOD = pow(2,64);

$userperms =  $CAN_PLAY | $CAN_DANCE | $CAN_SING | $CAN_BEGOD;

if($userperms & $CAN_DANCE)
    echo 'This will work';

if($userperms & $CAN_BEGOD)
    echo 'This will not work';

?>

Естественно, он вернет true для первой проверки, что меньше 2 ^ 63, однако для последней я назначаю его 2 ^ 64, что слишком велико для целогоневерно возвращает false.Есть ли способ заставить его работать больше 2 ^ 63?В противном случае я смогу использовать битовые перья только для 63 различных предметов.

Ответы [ 3 ]

1 голос
/ 17 сентября 2011

GMP приходит на ум, это инкапсулировано ( см. Полный код / ​​демо ):

$CAN_DANCE = Gmp(2);

$CAN_SING = Gmp(4);

$CAN_PLAY =  Gmp(8);

$CAN_BEGOD = Gmp(2)->pow(64);    

$userperms = Gmp($CAN_PLAY)->or($CAN_DANCE, $CAN_SING, $CAN_BEGOD);    

if($userperms->and($CAN_DANCE)->bool())
    echo 'This will work', "\n";

if($userperms->and($CAN_BEGOD)->bool())
    echo 'This will work', "\n";

Это будет работать с гораздо большими числами, однако числа - это ресурсы (Gmp::number()) или строки ((string) Gmp), и пока существует каждый экземпляр, объект Gmp также.

0 голосов
/ 30 сентября 2011

Вы можете попробовать использовать битовый массив:

$bitArray = array();
$bitArray[0] = $word0;
$bitArray[1] = $word1;
. 
.
.

Если вам нужны $ nFlags bits и $ bitsPerWord = 64, то вы создадите слова $ nFlags / $ bitsPerWord.

0 голосов
/ 17 сентября 2011

Поскольку эта функция возвращает int, возможно, вы могли бы использовать функцию gmp_pow (), а для вычисления результатов вы можете использовать gmp_or (), а для выражений if вы можете использовать gmp_and ()

...