php 移位运算符,PHP位运算符

位运算符允许对整型数中指定的位进行求值和操作。位运算符例子名称结果$a & $bAnd(按位与)将把 $a 和 $b 中都为 1 的位设为 1。

$a | $bOr(按位或)将把 $a 和 $b 中任何一个为 1 的位设为 1。

$a ^ $bXor(按位异或)将把 $a 和 $b 中一个为 1 另一个为 0 的位设为 1。

~ $aNot(按位取反)将 $a 中为 0 的位设为 1,反之亦然。

$a << $bShift left(左移)将 $a 中的位向左移动 $b 次(每一次移动都表示“乘以 2”)。

$a >> $bShift right(右移)将 $a 中的位向右移动 $b 次(每一次移动都表示“除以 2”)。

位移在 PHP 中是数学运算。向任何方向移出去的位都被丢弃。左移时右侧以零填充,符号位被移走意味着正负号不被保留。右移时左侧以符号位填充,意味着正负号被保留。

要用括号确保想要的优先级。例如 $a

& $b == true 先进行比较再进行按位与;而 ($a & $b) == true 则先进行按位与再进行比较。

要注意数据类型的转换。如果左右参数都是字符串,则位运算符将对字符的 ASCII 值进行操作。

PHP 的 ini 设定 error_reporting 使用了按位的值,

提供了关闭某个位的真实例子。要显示除了提示级别

之外的所有错误,php.ini 中是这样用的:

E_ALL & ~E_NOTICE具体运作方式是先取得 E_ALL 的值:

00000000000000000111011111111111

再取得 E_NOTICE 的值:

00000000000000000000000000001000

然后通过 ~ 将其取反:

11111111111111111111111111110111

最后再用按位与 AND(&)得到两个值中都设定了(为 1)的位:

00000000000000000111011111110111另外一个方法是用按位异或 XOR(^)来取得只在

其中一个值中设定了的位:

E_ALL ^ E_NOTICE

error_reporting 也可用来演示怎样置位。只显示错误和可恢复

错误的方法是:

E_ERROR | E_RECOVERABLE_ERROR也就是将 E_ERROR

00000000000000000000000000000001

和 E_RECOVERABLE_ERROR

00000000000000000001000000000000

用按位或 OR(|)运算符来取得在任何一个值中被置位的结果:

00000000000000000001000000000001

Example #1 整数的 AND,OR 和 XOR 位运算符

/*

* Ignore the top section,

* it is just formatting to make output clearer.

*/$format='(%1$2d = %1$04b) = (%2$2d = %2$04b)'.' %3$s (%4$2d = %4$04b)'."\n";

echo <

result value op test

--------- --------- -- ---------EOH;/*

* Here are the examples.

*/$values= array(0,1,2,4,8);$test=1+4;

echo"\n Bitwise AND \n";

foreach ($valuesas$value) {$result=$value&$test;printf($format,$result,$value,'&',$test);

}

echo"\n Bitwise Inclusive OR \n";

foreach ($valuesas$value) {$result=$value|$test;printf($format,$result,$value,'|',$test);

}

echo"\n Bitwise Exclusive OR (XOR) \n";

foreach ($valuesas$value) {$result=$value^$test;printf($format,$result,$value,'^',$test);

}?>

以上例程会输出:

--------- --------- -- ---------

result value op test

--------- --------- -- ---------

Bitwise AND

( 0 = 0000) = ( 0 = 0000) & ( 5 = 0101)

( 1 = 0001) = ( 1 = 0001) & ( 5 = 0101)

( 0 = 0000) = ( 2 = 0010) & ( 5 = 0101)

( 4 = 0100) = ( 4 = 0100) & ( 5 = 0101)

( 0 = 0000) = ( 8 = 1000) & ( 5 = 0101)

Bitwise Inclusive OR

( 5 = 0101) = ( 0 = 0000) | ( 5 = 0101)

( 5 = 0101) = ( 1 = 0001) | ( 5 = 0101)

( 7 = 0111) = ( 2 = 0010) | ( 5 = 0101)

( 5 = 0101) = ( 4 = 0100) | ( 5 = 0101)

(13 = 1101) = ( 8 = 1000) | ( 5 = 0101)

Bitwise Exclusive OR (XOR)

( 5 = 0101) = ( 0 = 0000) ^ ( 5 = 0101)

( 4 = 0100) = ( 1 = 0001) ^ ( 5 = 0101)

( 7 = 0111) = ( 2 = 0010) ^ ( 5 = 0101)

( 1 = 0001) = ( 4 = 0100) ^ ( 5 = 0101)

(13 = 1101) = ( 8 = 1000) ^ ( 5 = 0101)

Example #2 字符串的 XOR 运算符

echo12^9;// Outputs '5'echo"12"^"9";// Outputs the Backspace character (ascii 8)

// ('1' (ascii 49)) ^ ('9' (ascii 57)) = #8echo"hallo"^"hello";// Outputs the ascii values #0 #4 #0 #0 #0

// 'a' ^ 'e' = #4echo2^"3";// Outputs 1

// 2 ^ ((int)"3") == 1echo"2"^3;// Outputs 1

// ((int)"2") ^ 3 == 1?>

Example #3 整数的位移

/*

* Here are the examples.

*/echo"\n--- BIT SHIFT RIGHT ON POSITIVE INTEGERS ---\n";$val=4;$places=1;$res=$val>>$places;p($res,$val,'>>',$places,'copy of sign bit shifted into left side');$val=4;$places=2;$res=$val>>$places;p($res,$val,'>>',$places);$val=4;$places=3;$res=$val>>$places;p($res,$val,'>>',$places,'bits shift out right side');$val=4;$places=4;$res=$val>>$places;p($res,$val,'>>',$places,'same result as above; can not shift beyond 0');

echo"\n--- BIT SHIFT RIGHT ON NEGATIVE INTEGERS ---\n";$val= -4;$places=1;$res=$val>>$places;p($res,$val,'>>',$places,'copy of sign bit shifted into left side');$val= -4;$places=2;$res=$val>>$places;p($res,$val,'>>',$places,'bits shift out right side');$val= -4;$places=3;$res=$val>>$places;p($res,$val,'>>',$places,'same result as above; can not shift beyond -1');

echo"\n--- BIT SHIFT LEFT ON POSITIVE INTEGERS ---\n";$val=4;$places=1;$res=$val<

echo"\n--- BIT SHIFT LEFT ON NEGATIVE INTEGERS ---\n";$val= -4;$places=1;$res=$val<

* Ignore this bottom section,

* it is just formatting to make output clearer.

*/functionp($res,$val,$op,$places,$note='') {$format='%0'. (PHP_INT_SIZE*8) ."b\n";printf("Expression: %d = %d %s %d\n",$res,$val,$op,$places);

echo" Decimal:\n";printf(" val=%d\n",$val);printf(" res=%d\n",$res);

echo" Binary:\n";printf(' val='.$format,$val);printf(' res='.$format,$res);

if ($note) {

echo" NOTE:$note\n";

}

echo"\n";

}?>

以上例程在 32 位机器上的输出:

--- BIT SHIFT RIGHT ON POSITIVE INTEGERS ---

Expression: 2 = 4 >> 1

Decimal:

val=4

res=2

Binary:

val=00000000000000000000000000000100

res=00000000000000000000000000000010

NOTE: copy of sign bit shifted into left side

Expression: 1 = 4 >> 2

Decimal:

val=4

res=1

Binary:

val=00000000000000000000000000000100

res=00000000000000000000000000000001

Expression: 0 = 4 >> 3

Decimal:

val=4

res=0

Binary:

val=00000000000000000000000000000100

res=00000000000000000000000000000000

NOTE: bits shift out right side

Expression: 0 = 4 >> 4

Decimal:

val=4

res=0

Binary:

val=00000000000000000000000000000100

res=00000000000000000000000000000000

NOTE: same result as above; can not shift beyond 0

--- BIT SHIFT RIGHT ON NEGATIVE INTEGERS ---

Expression: -2 = -4 >> 1

Decimal:

val=-4

res=-2

Binary:

val=11111111111111111111111111111100

res=11111111111111111111111111111110

NOTE: copy of sign bit shifted into left side

Expression: -1 = -4 >> 2

Decimal:

val=-4

res=-1

Binary:

val=11111111111111111111111111111100

res=11111111111111111111111111111111

NOTE: bits shift out right side

Expression: -1 = -4 >> 3

Decimal:

val=-4

res=-1

Binary:

val=11111111111111111111111111111100

res=11111111111111111111111111111111

NOTE: same result as above; can not shift beyond -1

--- BIT SHIFT LEFT ON POSITIVE INTEGERS ---

Expression: 8 = 4 << 1

Decimal:

val=4

res=8

Binary:

val=00000000000000000000000000000100

res=00000000000000000000000000001000

NOTE: zeros fill in right side

Expression: 1073741824 = 4 << 28

Decimal:

val=4

res=1073741824

Binary:

val=00000000000000000000000000000100

res=01000000000000000000000000000000

Expression: -2147483648 = 4 << 29

Decimal:

val=4

res=-2147483648

Binary:

val=00000000000000000000000000000100

res=10000000000000000000000000000000

NOTE: sign bits get shifted out

Expression: 0 = 4 << 30

Decimal:

val=4

res=0

Binary:

val=00000000000000000000000000000100

res=00000000000000000000000000000000

NOTE: bits shift out left side

--- BIT SHIFT LEFT ON NEGATIVE INTEGERS ---

Expression: -8 = -4 << 1

Decimal:

val=-4

res=-8

Binary:

val=11111111111111111111111111111100

res=11111111111111111111111111111000

NOTE: zeros fill in right side

Expression: -2147483648 = -4 << 29

Decimal:

val=-4

res=-2147483648

Binary:

val=11111111111111111111111111111100

res=10000000000000000000000000000000

Expression: 0 = -4 << 30

Decimal:

val=-4

res=0

Binary:

val=11111111111111111111111111111100

res=00000000000000000000000000000000

NOTE: bits shift out left side, including sign bit

以上例程在 64 位机器上的输出:

--- BIT SHIFT RIGHT ON POSITIVE INTEGERS ---

Expression: 2 = 4 >> 1

Decimal:

val=4

res=2

Binary:

val=0000000000000000000000000000000000000000000000000000000000000100

res=0000000000000000000000000000000000000000000000000000000000000010

NOTE: copy of sign bit shifted into left side

Expression: 1 = 4 >> 2

Decimal:

val=4

res=1

Binary:

val=0000000000000000000000000000000000000000000000000000000000000100

res=0000000000000000000000000000000000000000000000000000000000000001

Expression: 0 = 4 >> 3

Decimal:

val=4

res=0

Binary:

val=0000000000000000000000000000000000000000000000000000000000000100

res=0000000000000000000000000000000000000000000000000000000000000000

NOTE: bits shift out right side

Expression: 0 = 4 >> 4

Decimal:

val=4

res=0

Binary:

val=0000000000000000000000000000000000000000000000000000000000000100

res=0000000000000000000000000000000000000000000000000000000000000000

NOTE: same result as above; can not shift beyond 0

--- BIT SHIFT RIGHT ON NEGATIVE INTEGERS ---

Expression: -2 = -4 >> 1

Decimal:

val=-4

res=-2

Binary:

val=1111111111111111111111111111111111111111111111111111111111111100

res=1111111111111111111111111111111111111111111111111111111111111110

NOTE: copy of sign bit shifted into left side

Expression: -1 = -4 >> 2

Decimal:

val=-4

res=-1

Binary:

val=1111111111111111111111111111111111111111111111111111111111111100

res=1111111111111111111111111111111111111111111111111111111111111111

NOTE: bits shift out right side

Expression: -1 = -4 >> 3

Decimal:

val=-4

res=-1

Binary:

val=1111111111111111111111111111111111111111111111111111111111111100

res=1111111111111111111111111111111111111111111111111111111111111111

NOTE: same result as above; can not shift beyond -1

--- BIT SHIFT LEFT ON POSITIVE INTEGERS ---

Expression: 8 = 4 << 1

Decimal:

val=4

res=8

Binary:

val=0000000000000000000000000000000000000000000000000000000000000100

res=0000000000000000000000000000000000000000000000000000000000001000

NOTE: zeros fill in right side

Expression: 4611686018427387904 = 4 << 60

Decimal:

val=4

res=4611686018427387904

Binary:

val=0000000000000000000000000000000000000000000000000000000000000100

res=0100000000000000000000000000000000000000000000000000000000000000

Expression: -9223372036854775808 = 4 << 61

Decimal:

val=4

res=-9223372036854775808

Binary:

val=0000000000000000000000000000000000000000000000000000000000000100

res=1000000000000000000000000000000000000000000000000000000000000000

NOTE: sign bits get shifted out

Expression: 0 = 4 << 62

Decimal:

val=4

res=0

Binary:

val=0000000000000000000000000000000000000000000000000000000000000100

res=0000000000000000000000000000000000000000000000000000000000000000

NOTE: bits shift out left side

--- BIT SHIFT LEFT ON NEGATIVE INTEGERS ---

Expression: -8 = -4 << 1

Decimal:

val=-4

res=-8

Binary:

val=1111111111111111111111111111111111111111111111111111111111111100

res=1111111111111111111111111111111111111111111111111111111111111000

NOTE: zeros fill in right side

Expression: -9223372036854775808 = -4 << 61

Decimal:

val=-4

res=-9223372036854775808

Binary:

val=1111111111111111111111111111111111111111111111111111111111111100

res=1000000000000000000000000000000000000000000000000000000000000000

Expression: 0 = -4 << 62

Decimal:

val=-4

res=0

Binary:

val=1111111111111111111111111111111111111111111111111111111111111100

res=0000000000000000000000000000000000000000000000000000000000000000

NOTE: bits shift out left side, including sign bit

Warning

不要在 32 位系统下向右移超过 32 位。不要在结果可能超过 32 的情况下左移。使用 gmp 扩展对超出 PHP_INT_MAX 的数值来进行位操作。

参见 pack(),unpack(),gmp_and(),gmp_or(),gmp_xor(),gmp_testbit() 和 gmp_clrbit()。

20150824204951_7209.png add

a note

User Contributed Notes 43 notes

up

down

46wbcarts

at juno dot com ?

3 years ago

BITWISE FLAGS for Custom

PHP Objects

Sometimes I need a custom PHP Object that holds several boolean TRUE or FALSE values. I could easily include a variable for each of them, but as always, code has a way to get unweildy pretty fast. A more intelligent approach always seems to be the answer, even

if it seems to be overkill at first.

I start with an abstract base class which will hold a single integer variable called $flags. This simple integer can hold 32 TRUE or FALSE boolean values. Another thing to consider is to just set certain BIT values without disturbing any of the other BITS --

so included in the class definition is the setFlag($flag, $value) function, which will set only the chosen bit. Here's the abstract base class definition:

# BitwiseFlag.phpabstract classBitwiseFlag{

protected$flags;/*

* Note: these functions are protected to prevent outside code

* from falsely setting BITS. See how the extending class 'User'

* handles this.

*

*/protected functionisFlagSet($flag)

{

return (($this->flags&$flag)

==$flag);

}

protected functionsetFlag($flag,$value)

{

if($value)

{$this->flags|=$flag;

}

else

{$this->flags&=

~$flag;

}

}

}?>

The class above is abstract and cannot be instantiated, so an extension is required. Below is a simple extension called User -- which is severely truncated for clarity. Notice I am defining const variables AND methods to use them.

# User.phprequire('BitwiseFlag.php');

classUserextendsBitwiseFlag{

constFLAG_REGISTERED=1;//

BIT #1 of $flags has the value 1constFLAG_ACTIVE=2;// BIT #2 of $flags has the value 2constFLAG_MEMBER=4;// BIT #3 of $flags has the value 4constFLAG_ADMIN=8;// BIT #4 of $flags has the value 8public functionisRegistered(){

return$this->isFlagSet(self::FLAG_REGISTERED);

}

public functionisActive(){

return$this->isFlagSet(self::FLAG_ACTIVE);

}

public functionisMember(){

return$this->isFlagSet(self::FLAG_MEMBER);

}

public functionisAdmin(){

return$this->isFlagSet(self::FLAG_ADMIN);

}

public functionsetRegistered($value){$this->setFlag(self::FLAG_REGISTERED,$value);

}

public functionsetActive($value){$this->setFlag(self::FLAG_ACTIVE,$value);

}

public functionsetMember($value){$this->setFlag(self::FLAG_MEMBER,$value);

}

public functionsetAdmin($value){$this->setFlag(self::FLAG_ADMIN,$value);

}

public function__toString(){

return'User ['.

($this->isRegistered()

?'REGISTERED':'')

.

($this->isActive()

?' ACTIVE':'')

.

($this->isMember()

?' MEMBER':'')

.

($this->isAdmin()

?' ADMIN':'')

.']';

}

}?>

This seems like a lot of work, but we have addressed many issues, for example, using and maintaining the code is easy, and the getting and setting of flag values make sense. With the User class, you can now see how easy and intuitive bitwise flag operations

become.

require('User.php')$user= newUser();$user->setRegistered(true);$user->setActive(true);$user->setMember(true);$user->setAdmin(true);

echo$user;//

outputs: User [REGISTERED ACTIVE MEMBER ADMIN]?>

up

down

6zlel

grxnslxves13 at hotmail dot com~=s/x/ee/g ?

9 years ago

I refer to Eric Swanson's

post on Perl VS PHP's implementation of xor.

Actually, this is not an issue with the implementation of XOR, but a lot more to do with the lose-typing policy that PHP adopts.

Freely switching between int and float is good for most cases, but problems happen when your value is near the word size of your machine. Which is to say, 32-bit machines will encounter problems with values that hover around 0x80000000 - primarily because PHP

does not support unsigned integers.

using bindec/decbin would address this issue as a work-around to do unsigned-int xor, but here's the real picture (i'm not claiming that this code will perform better, but this would be a better pedagogical code):

functionunsigned_xor32($a,$b)

{$a1=$a&0x7FFF0000;$a2=$a&0x0000FFFF;$a3=$a&0x80000000;$b1=$b&0x7FFF0000;$b2=$b&0x0000FFFF;$b3=$b&0x80000000;$c= ($a3!=$b3)

?0x80000000:0;

return (($a1^$b1)

|($a2^$b2))

+$c;

}$x=3851235679;$y=43814;

echo"

This is the value we want";

echo"

3851262585";

echo"

The result of a native xor operation on integer values is treated as a signed integer";

echo"

".($x^$y);

echo"

We therefore perform the MSB separately";

echo"

".unsigned_xor32($x,$y);?>

This is really foundation stuff, but for those of you who missed this in college, there seems to be something on 2's complement here:

http://www.evergreen.edu/biophysics/technotes/program/2s_comp.htm

up

down

3sag

at ich dot net ?

2 years ago

me reimplement for bitwise

NOT (~)

protected function flipBin($number) {

$bin = str_pad(base_convert($number, 10, 2), 32, 0, STR_PAD_LEFT);

for ($i = 0; $i < 32; $i++) {

switch ($bin{$i}) {

case '0' :

$bin{$i} = '1';

break;

case '1' :

$bin{$i} = '0';

break;

}

}

return bindec($bin);

}

the benefit is, it works with numbers greater MAX_INT

up

down

3vivekanand

dot pathak25 at gmail dot com ?

2 years ago

$a = 9;

$b = 10;

echo $a & $b;

place value 128 64 32 16 8 4 2 1

$a 0 0 0 0 1 0 0 1 =9

$b 0 0 0 0 1 0 1 0 =10

result 8

only bit they share together is the 8 bit. So 8 gets returned.

$a = 36;

$b = 103;

echo $a & $b;

place value 128 64 32 16 8 4 2 1

$a 0 0 1 0 0 1 0 0 =36

$b 0 1 1 0 0 1 1 1 =103

result 32+4 = 36

the only bits these two share together are the bits 32 and 4 which when added together return 36.

$a = 9;

$b = 10;

echo $a | $b;

place value 128 64 32 16 8 4 2 1

$a 0 0 0 0 1 0 0 1 =9

$b 0 0 0 0 1 0 1 0 =10

result 8+2+1 = 11

3 bits set, in the 8, 2, and 1 column.add those up 8+2+1 and you get 11

$a = 9;

$b = 10;

echo $a ^ $b;

place value 128 64 32 16 8 4 2 1

$a 0 0 0 0 1 0 0 1 =9

$b 0 0 0 0 1 0 1 0 =10

result 2+1 = 3

the 2 bit and the 1 bit that they each have set but don't share. Soooo 2+1 = 3

up

down

3erich

at seachawaii dot com ?

2 years ago

Just a note regarding negative

shift values, as the documentation states each shift is an integer multiply or divide (left or right respectively) by 2. That means a negative shift value (the right hand operand) effects the sign of the shift and NOT the direction of the shift as I would

have expected.

FE. 0xff >> -2 results in 0x0

and 0xff << -2 result in 0xFFFFFFFFC0000000 (dependant on PHP_INT_MAX)

up

down

4cw3theophilus

at gmail dot com ?

6 years ago

For those who are looking

for a circular bit shift function in PHP (especially useful for cryptographic functions) that works with negtive values, here is a little function I wrote:

(Note: It took me almost a whole day to get this to work with negative $num values (I couldn't figure out why it sometimes worked and other times didn't), because PHP only has an arithmatic and not a logical bitwise right shift like I am used to. I.e. 0x80000001>>16

will ouputs (in binary) "1111 1111 1111 1111 1000 0000 0000 0000" instead of "0000 0000 0000 0000 1000 0000 0000 0000" like you would expect. To fix this you have to apply the mask (by bitwise &) equal to 0x7FFFFFFF right shifted one less than the offset you

are shifting by.)

functioncircular_shift($num,$offset)

{//Do a nondestructive circular bitwise shift, if offset positive shift left, if negative shift right$num=(int)$num;$mask=0x7fffffff;//Mask

to cater for the fact that PHP only does arithmatic right shifts and not logical i.e. PHP doesn't give expected output when right shifting negative valuesif ($offset>0)

{$num=($num<

| (($num>>(32-$offset%32))

& ($mask>>(31-$offset%32)));

}

elseif ($offset<0){$offset=abs($offset);$num=(($num>>$offset%32)

& ($mask>>(-1+$offset%32)))

| ($num<32-$offset%32));

}

return$num;

}?>

up

down

3m0sh

at hotmail dot com ?

7 years ago

@greenone - nice function,

thanks. I've adapted it for key usage:

functionbitxor($str,$key)

{$xorWidth=PHP_INT_SIZE*8;// split$o1=str_split($str,$xorWidth);$o2=str_split(str_pad('',strlen($str),$key),$xorWidth);$res='';$runs=count($o1);

for($i=0;$i

^bindec($o2[$i]));

return$res;

}?>

up

down

3Eric

Swanson ?

9 years ago

Perl vs. PHP implementation

of the ^ operator:

After attempting to translate a Perl module into PHP, I realized that Perl's implementation of the ^ operator is different than the PHP implementation. By default, Perl treats the variables as floats and PHP as integers. I was able to verify the PHP use of

the operator by stating "use integer;" within the Perl module, which output the exact same result as PHP was using.

The logical decision would be to cast every variable as (float) when using the ^ operator in PHP. However, this will not yield the same results. After about a half hour of banging my head against the wall, I discovered a gem and wrote a function using the

binary-decimal conversions in PHP.

/*

not having much experience with bitwise operations, I cannot tell you that this is the BEST solution, but it certainly is a solution that finally works and always returns the EXACT same result Perl provides.

*/

function binxor($a, $b) {

return bindec(decbin((float)$a ^ (float)$b));

}

//normal PHP code will not yeild the same result as Perl

$result = 3851235679 ^ 43814; //= -443704711

//to get the same result as Perl

$result = binxor(3851235679, 43814); //= 3851262585

//YIPPEE!!!

//to see the differences, try the following

$a = 3851235679 XOR 43814;

$b = 3851235679 ^ 43814; //integer result

$c = (float)3851235679 ^ (float)43814; //same as $b

$d = binxor(3851235679, 43814); //same as Perl!!

echo("A: $a

");

echo("B: $b

");

echo("C: $c

");

echo("D: $d

");

up

down

10grayda

dot NOSPAM at DONTSPAM dot solidinc dot org ?

6 years ago

Initially, I found bitmasking

to be a confusing concept and found no use for it. So I've whipped up this code snippet in case anyone else is confused:

// The various details a vehicle can have$hasFourWheels=1;$hasTwoWheels=2;$hasDoors=4;$hasRedColour=8;$bike=$hasTwoWheels;$golfBuggy=$hasFourWheels;$ford=$hasFourWheels|$hasDoors;$ferrari=$hasFourWheels|$hasDoors|$hasRedColour;$isBike=$hasFourWheels&$bike;#

False, because $bike doens't have four wheels$isGolfBuggy=$hasFourWheels&$golfBuggy;#

True, because $golfBuggy has four wheels$isFord=$hasFourWheels&$ford;#

True, because $ford $hasFourWheels?>

And you can apply this to a lot of things, for example, security:

// Security permissions:$writePost=1;$readPost=2;$deletePost=4;$addUser=8;$deleteUser=16;// User groups:$administrator=$writePost|$readPosts|$deletePosts|$addUser|$deleteUser;$moderator=$readPost|$deletePost|$deleteUser;$writer=$writePost|$readPost;$guest=$readPost;// function to check for permissionfunctioncheckPermission($user,$permission)

{

if($user&$permission)

{

returntrue;

} else {

returnfalse;

}

}// Now we apply all of this!if(checkPermission($administrator,$deleteUser))

{deleteUser("Some

User");# This is executed because $administrator can $deleteUser}?>

Once you get your head around it, it's VERY useful! Just remember to raise each value by the power of two to avoid problems

up

down

6ivoras

at gmail dot com ?

4 years ago

As an additional curiosity,

for some reason the result of the operation ("18" & "32") is "10". In other words, try avoiding using the binary operators on strings :)

up

down

10?

10 years ago

A bitwise operators practical

case :

// We want to know the red, green and blue values of this color :$color=0xFEA946;$red=$color>>16;$green= ($color&0x00FF00)

>>8;$blue=$color&0x0000FF;printf('Red

: %X (%d), Green : %X (%d), Blue : %X (%d)',$red,$red,$green,$green,$blue,$blue)

;// Will display...

// Red : FE (254), Green : A9 (169), Blue : 46 (70)?>

up

down

4zooly

at globmi dot com ?

5 years ago

Here is an example for bitwise

leftrotate and rightrotate.

Note that this function works only with decimal numbers - other types can be converted with pack().

functionrotate($decimal,$bits)

{$binary=decbin($decimal);

return (bindec(substr($binary,$bits).substr($binary,0,$bits))

);

}// Rotate 124 (1111100) to the left with 1 bitsechorotate(124,1);// = 121 (1111001)

// Rotate 124 (1111100) to the right with 3 bitsechorotate(124,

-3);// = 79 (1001111)?>

up

down

3josh

at joshstrike dot com ?

4 years ago

More referencing this for

myself than anything... if you need to iterate through every possible binary combination where $n number of flags are set to 1 in a mask of $bits length:

echomasksOf(3,10);

functionmasksOf($n,$bits)

{$u=pow(2,$bits)-1;//start

value, full flags on.$masks= array();

while ($u>0)

{$z=numflags($u);

if ($z==$n)array_push($masks,$u);$u--;

}

return ($masks);

}

functionnumflags($n)

{$k=0;

while ($n) {$k+=$n&1;$n=$n>>1;

}

return ($k);// alternately:

// $u = 0;

// for ($k=1;$k<=$n;$k*=2) {

// $u+=($n&$k?1:0);

// }

// return ($u);}?>

up

down

4spencer-p-moy

at example dot com ?

3 years ago

The NOT or complement operator

( ~ ) and negative binary numbers can be confusing.

~2 = -3 because you use the formula ~x = -x - 1 The bitwise complement of a decimal number is the negation of the number minus 1.

NOTE: just using 4 bits here for the examples below but in reality PHP uses 32 bits.

Converting a negative decimal number (ie: -3) into binary takes 3 steps:

1) convert the positive version of the decimal number into binary (ie: 3 = 0011)

2) flips the bits (ie: 0011 becomes 1100)

3) add 1 (ie: 1100 + 0001 = 1101)

You might be wondering how does 1101 = -3. Well PHP uses the method "2's complement" to render negative binary numbers. If the left most bit is a 1 then the binary number is negative and you flip the bits and add 1. If it is 0 then it is positive and you don't

have to do anything. So 0010 would be a positive 2. If it is 1101, it is negative and you flip the bits to get 0010. Add 1 and you get 0011 which equals -3.

up

down

网友评论

文明上网理性发言,请遵守 新闻评论服务协议我要评论

47d507a036d4dd65488c445c0974b649.png

立即提交

专题推荐064df72cb40df78e80e61b7041ee044f.png独孤九贱-php全栈开发教程

全栈 100W+

主讲:Peter-Zhu 轻松幽默、简短易学,非常适合PHP学习入门

7dafe36c040e31d783922649aefe0be1.png玉女心经-web前端开发教程

入门 50W+

主讲:灭绝师太 由浅入深、明快简洁,非常适合前端学习入门

04246fdfe8958426b043c89ded0857f1.png天龙八部-实战开发教程

实战 80W+

主讲:西门大官人 思路清晰、严谨规范,适合有一定web编程基础学习

php中文网:公益在线php培训,帮助PHP学习者快速成长!

Copyright 2014-2020 https://www.php.cn/ All Rights Reserved | 苏ICP备2020058653号-1e6cebb680dfe320dad7e62bd6442c3a6.gif

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值