Jump to content


Photo

bitwise operators


  • Please log in to reply
23 replies to this topic

#1 Zane

Zane
  • Administrators
  • Advanced Member
  • 4,134 posts

Posted 29 October 2006 - 06:00 PM

Every now and again I stumble on something about PHP I've never heard about.
I was looking at Operator Precedence and found a bitwise operator.

I looked further into it and found out there were more of those, but I have no clue where or when I would use them.  I can't understand the examples.

Can anyone enlighten me here.  Gimme a scenario were I'd use a bitwise operator?
Thanks

btn_donate_SM.gif Want to thank me? Contribute to my PayPal piggy-bank
 

172938.png

#2 ignace

ignace
  • Moderators
  • Now mod flavored
  • 6,431 posts
  • LocationBelgium

Posted 29 October 2006 - 06:11 PM

well finally someone with zero replies and a question i can answer :D

using bitwise operator with variables:

<?php
# the bitwise operator
$value1 = "ignace";
$value2 &= $value1;

echo $value2;
?>

so $value2 now holds the value of $value1, however $value2 does not hold a copy no it holds a reference to the variable $value1, meaning that whenever i change the value of $value2 the value of $value1 will be changed too. If you have any experience with c++ you will know that $value2 then holds the address of $value1 on the memory (not really important now, but nice to know)

using bitwise operator with functions:

<?php
$value1 = "ignace";

function insertIt(&$value)
{
   $value = "not ignace";
}

insertIt($value1);

echo $value1; # output: not ignace
?>


#3 Zane

Zane
  • Administrators
  • Advanced Member
  • 4,134 posts

Posted 29 October 2006 - 06:17 PM

Thanks for the response.
&= is an assignment operator not a bitwise.
Assign by reference I believe it's called.

I understand how references work, I was wondering how such operators like these work

$a & $b
$a | $b
$a ^ $b
~ $a
$a << $b
$a >> $b

btn_donate_SM.gif Want to thank me? Contribute to my PayPal piggy-bank
 

172938.png

#4 Barand

Barand
  • Moderators
  • Sen . ( ile || sei )
  • 18,025 posts

Posted 29 October 2006 - 07:00 PM

Bitwise operators work on the individual bits in a value (as it says on the tin)

Bitwise 'AND'
$a & $b

bits in the result are set only if the corresponding bit is set in both $a and $b
$a = 7     0111
$b = 13    1101
$a & $b    0101  = 5
So you can use it to turn bits 'OFF' in $a by ANDing with a value with a zero in that position

++++++++++++++++++++++++++++++++++++++++++++++
Bitwise 'OR'
$a | $b

bits in the result are set if 1 or both the correspondings bit set $a and $b
$a = 7     0111
$b = 8     1000
$a | $b    1111  = 15
So you can use it to turn bits 'ON' in $a by ORing with a value with a 1 in that position

++++++++++++++++++++++++++++++++++++++++++++++++
Exclusive OR (XOR)
$a ^ $b

bits in the result are set if 1 or other but not both the correspondings bit set $a and $b
$a = 7     0111
$b = 13    1101
$a ^ $b    1010  = 6
Note the process is reversible by repeating the operation
]$a = 6     1010
$b = 13    1101
$a ^ $b    0111  = 7

Can be used for simple encryption, xor each char with a value and repeat to get it back.
Also in grapbics, XOR drawing mode is used for rubber-banding.

+++++++++++++++++++++++++++++++++++++++++++++++++++++
NOT
~ $a

Simply reverses all the bits.
$a = 9    1001
~$a       0110  = 6
++++++++++++++++++++++++++++++++++++++++++++++++++++++
Left shift
$a << $b

Moves all the bits to left and pads with 0 at right
$a = 4   0100
$a << 1  1000 = 8   quick multiply by 2

++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Right shift
$a >> $b

Moves all the bits to right and pads with 0 at left
$a = 4   0100
$a >> 1  0010 = 2   quick divide by 2
++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Useful used in combination. Suppose you have a color value of 0x336699 and you want the green component value
]
<?php
$color = 0x336699;
$green = ($color >> 8) & 0xFF;  
echo dechex($green);            // --> 0x66
?>

If you are still using mysql_ functions, STOP! Use mysqli_ or PDO. The longer you leave it the more you will have to rewrite.

Donations gratefully received






moon.png

|baaGrid| easy data tables - and more
|baaChart| easy line, column and pie charts

#5 Zane

Zane
  • Administrators
  • Advanced Member
  • 4,134 posts

Posted 30 October 2006 - 06:28 PM

Wow
I completely understand how it works
but I have no clue why I would use it now.
I can't spot the convenience of it
Thank you for the extensive examples though Barrand

I'm sure one day something will spark and I'll need to dig deep into the binary aspects of what I'm doing.
omg my brain hurts from that one.
I knew I shouldn't have asked such a question...lol

btn_donate_SM.gif Want to thank me? Contribute to my PayPal piggy-bank
 

172938.png

#6 roopurt18

roopurt18
  • Staff Alumni
  • Advanced Member
  • 3,749 posts
  • LocationCalifornia, southern

Posted 30 October 2006 - 06:33 PM

User group permissions:

http://www.phpfreaks...c,110890.0.html
PHP Forms : Part I | Part II

JavaScript: Singleton

http://www.rbredlau.com

#7 Zane

Zane
  • Administrators
  • Advanced Member
  • 4,134 posts

Posted 30 October 2006 - 06:50 PM

In reference to this post
http://www.phpfreaks....html#msg450649

So to check my understanding..using as little jargon as possible.

At the beginning you have NO permissions..meaning just that
then say you want to allow them to delete a user
Delete a user has it's own numeric ...hex..value..whatever
say 0x00000064

if I want to append that permissioin to the $perms variable I use the | operator?
$perms = $perms | 0x00000064

Considering I don't use constants in this example which I know you preached on so much and I'd like to say I agree on but for the sake of understanding...yeah

and I validate it with the & operator?
if($perms & 0x00000064) //Can delete users

Say I did it vice versa?

$perms = $perms & 0x00000064;
if($perms | 0x00000064) //Then what

btn_donate_SM.gif Want to thank me? Contribute to my PayPal piggy-bank
 

172938.png

#8 roopurt18

roopurt18
  • Staff Alumni
  • Advanced Member
  • 3,749 posts
  • LocationCalifornia, southern

Posted 30 October 2006 - 07:05 PM

<?php
$perms = $perms & 0x00000064;
if($perms | 0x00000064) //Then what
?>

<?php
// $perms is empty: 0x00000000
$perms = $perms & 0x00000064;
// $perms is assigned the result of 0x00000000 & 0x00000064, which will be 0x00000000
$perms = $perms & 0x00000064;
// evaluate expression: $perms | 0x00000064 -> 0x00000000 | 0x00000064 -> 0x00000064
// Since 0x00000064 evaluates as true, the body of the if statement executes
if($perms | 0x00000064)
?>

Doing it the correct way:
<?php
// $perms is empty: 0x00000000
// $perms | 0x00000002 -> 0x00000002
$perms = $perms | 0x00000002;

// later in the code, after $perms has had many more assignments
// $perms & 0x00000002 -> 0x0000AF73 & 0x00000002 -> 0x00000002, so the body of the if evaluates
if($perms & 0x00000002)

// later in the code, after $perms as been assigned more
// $perms & 0x00000002 -> 0x0000BBC4 -> 0x00000000, so the body of the if DOES NOT evaluate
if($perms & 0x00000002)
?>

PHP Forms : Part I | Part II

JavaScript: Singleton

http://www.rbredlau.com

#9 Zane

Zane
  • Administrators
  • Advanced Member
  • 4,134 posts

Posted 30 October 2006 - 07:26 PM

ReCap again...
alright

I'm a permissionless user
$zanesPerms = 0x00000000;

the Admin gives me posting rights
$zanesPerms = $zanesPerms | 0x00000128
//$zanePerms now equals ... 0x00000128?

if the Admin then gave me Delete user rights... 0x00000064
Explain to me the way barand did, how the variable is changed.

would zanesPerms be 0x00000192? or something else and why

I appreciate your help a lot

btn_donate_SM.gif Want to thank me? Contribute to my PayPal piggy-bank
 

172938.png

#10 Barand

Barand
  • Moderators
  • Sen . ( ile || sei )
  • 18,025 posts

Posted 30 October 2006 - 08:57 PM

Here's what may be a more familiar example (error reporting levels)
[pre]
1    E_ERROR 
2    E_WARNING 
4    E_PARSE 
8    E_NOTICE 
16  E_CORE_ERROR 
32  E_CORE_WARNING 
64  E_COMPILE_ERROR 
128  E_COMPILE_WARNING 
256  E_USER_ERROR 
512  E_USER_WARNING 
1024 E_USER_NOTICE 
2047 E_ALL 
2048 E_STRICT

E_ALL              111111111111
E_NOTICE            000000001000
~E_NOTICE          111111110111
                   
E_ALL & ~E_NOTICE  111111110111
[/pre]
If you are still using mysql_ functions, STOP! Use mysqli_ or PDO. The longer you leave it the more you will have to rewrite.

Donations gratefully received






moon.png

|baaGrid| easy data tables - and more
|baaChart| easy line, column and pie charts

#11 roopurt18

roopurt18
  • Staff Alumni
  • Advanced Member
  • 3,749 posts
  • LocationCalifornia, southern

Posted 30 October 2006 - 10:38 PM

One of the things you're missing Zanus is in your hex values you're setting multiple bits as ones for a single permission:

Ignoring leading zeros, 0x00000128 in binary is: 0001 0010 1000
You don't need 3 ones in your permission constant to specify 1 setting.

So let's say you have the following:

0x01 -> 0000 0001
0x02 -> 0000 0010

0x01 & 0x02 -> 0000 0001 & 0000 0010 -> 0000 0000 (none of them have a 1 in the matching column of the other)
0x01 | 0x02 -> 0000 0001 | 0000 0010 -> 0000 0011 (the result has a 1 where any of the inputs had a 1)
0x01 & ~0x02 -> 0000 0001 & ~0000 0010 -> 0000 0001 & 1111 1101 -> 0000 0001
PHP Forms : Part I | Part II

JavaScript: Singleton

http://www.rbredlau.com

#12 Zane

Zane
  • Administrators
  • Advanced Member
  • 4,134 posts

Posted 30 October 2006 - 11:38 PM

Ok...it's making much more sense now

So say I wanted to show all errors except

E_CORE_WARNING - 32 bits
E_COMPILE_WARNING - 128 bits
E_USER_WARNING - 512 bits

would I say?
in a non-constant sense
$showErrors = 11111111111;                 //E_ALL
$showErrors = $showErrors & ~100000         // ~E_CORE_WARNING
$showErrors = $showErrors & ~10000000     // E_COMPILE_WARNING
$showErrors = $showErrors & ~100000000   //E_USER_WARNING
error_reporting($showErrors);

or another quesiton
would $showErrors
then equal?
10101011111

btn_donate_SM.gif Want to thank me? Contribute to my PayPal piggy-bank
 

172938.png

#13 Barand

Barand
  • Moderators
  • Sen . ( ile || sei )
  • 18,025 posts

Posted 30 October 2006 - 11:49 PM

Yes.

To verify
<?php
$level = E_ALL & ~(E_CORE_WARNING | E_COMPILE_WARNING | E_USER_WARNING) ;
echo decbin($level);    
?>

--> 10101011111
If you are still using mysql_ functions, STOP! Use mysqli_ or PDO. The longer you leave it the more you will have to rewrite.

Donations gratefully received






moon.png

|baaGrid| easy data tables - and more
|baaChart| easy line, column and pie charts

#14 Zane

Zane
  • Administrators
  • Advanced Member
  • 4,134 posts

Posted 31 October 2006 - 12:09 AM

OMG I learned something!
thanks so much guys

Now I just have to grasp the other operators.
In retrospect I learned that if I do
$a & ~$b

$b is basically removed from $a IF it exists....or turned off essentially.

Just gonna do another test in my head ... I'm not even using a PHP server at all BTW.  This is all straight up calc.exe, php.net and you guys.

So Considering
echo decbin(E_ALL & ~(E_CORE_WARNING | E_COMPILE_WARNING | E_USER_WARNING));
returns 10101011111

echo decbin(E_ALL | ~(E_CORE_WARNING & E_COMPILE_WARNING & E_USER_WARNING));
should return.....
-
-
-time goes by
-
E_CORE_WARNING (0000100000) & E_COMPILE_WARNING(0010000000) & E_USER_WARNING(1000000000)
(0000100000 & 0010000000 & 1000000000) = 0000000000
~0000000000 = 1111111111
E_ALL(1111111111) & 1111111111 = 0000000000



Furthermore...
say I went
error_reporting(E_ALL >> 5)
translating to.......
1111111111 -> 0000011111 -> 31
31 translating to E_CORE_ERROR I guess since 32 hasn't been reached yet...right?

btn_donate_SM.gif Want to thank me? Contribute to my PayPal piggy-bank
 

172938.png

#15 Barand

Barand
  • Moderators
  • Sen . ( ile || sei )
  • 18,025 posts

Posted 31 October 2006 - 12:27 AM

No

31 is all these

1    E_ERROR 
2    E_WARNING 
4    E_PARSE 
8    E_NOTICE 
16  E_CORE_ERROR
If you are still using mysql_ functions, STOP! Use mysqli_ or PDO. The longer you leave it the more you will have to rewrite.

Donations gratefully received






moon.png

|baaGrid| easy data tables - and more
|baaChart| easy line, column and pie charts

#16 Zane

Zane
  • Administrators
  • Advanced Member
  • 4,134 posts

Posted 31 October 2006 - 12:35 AM

So is that true for all numbers
17 through 31

here I am at another interesting point.
say I wanted to test such a question
with a loop

for($i=17;$i<32;$i++) {
  if(decbin(31) | decbin($i))
     echo "$i is all of them";
}
would that work?

btn_donate_SM.gif Want to thank me? Contribute to my PayPal piggy-bank
 

172938.png

#17 Barand

Barand
  • Moderators
  • Sen . ( ile || sei )
  • 18,025 posts

Posted 31 October 2006 - 12:44 AM

if it was your intention to print
17 is all of them
18 is all of them
19 is all of them
20 is all of them
21 is all of them
22 is all of them
23 is all of them
24 is all of them
25 is all of them
26 is all of them
27 is all of them
28 is all of them
29 is all of them
30 is all of them
31 is all of them
then it works ;)
If you are still using mysql_ functions, STOP! Use mysqli_ or PDO. The longer you leave it the more you will have to rewrite.

Donations gratefully received






moon.png

|baaGrid| easy data tables - and more
|baaChart| easy line, column and pie charts

#18 Zane

Zane
  • Administrators
  • Advanced Member
  • 4,134 posts

Posted 31 October 2006 - 12:52 AM

eh..I was just wondering since the numbers 17 through 31
are both greater than 16 and NOT a power of two
that they would all be classified as
ALL of these
----------------------
1    E_ERROR
2    E_WARNING
4    E_PARSE
8    E_NOTICE
16  E_CORE_ERROR

I'm assuming they are


I just wrote the loop wrong...
that IF will always return true regardless I just realized...unless the result is 0



btn_donate_SM.gif Want to thank me? Contribute to my PayPal piggy-bank
 

172938.png

#19 Barand

Barand
  • Moderators
  • Sen . ( ile || sei )
  • 18,025 posts

Posted 31 October 2006 - 12:56 AM

try
<?php
$ev = array(
    1  =>  'E_ERROR', 
    2  =>  'E_WARNING', 
    4  =>  'E_PARSE', 
    8  =>  'E_NOTICE', 
    16 =>  'E_CORE_ERROR'
);

echo '<pre>';
for($i=17;$i<32;$i++) {
    echo "<br>$i = ";
    foreach ($ev as $k=>$v) {
        if ($i & $k) echo "$v($k), ";                          // edited to show bit value
    }
}
echo '</pre>';
?>

EDIT by zanus
Edit by Barand to show results with bit values

returns


17 = E_ERROR(1), E_CORE_ERROR(16)
18 = E_WARNING(2), E_CORE_ERROR(16)
19 = E_ERROR(1), E_WARNING(2), E_CORE_ERROR(16)
20 = E_PARSE(4), E_CORE_ERROR(16)
21 = E_ERROR(1), E_PARSE(4), E_CORE_ERROR(16)
22 = E_WARNING(2), E_PARSE(4), E_CORE_ERROR(16)
23 = E_ERROR(1), E_WARNING(2), E_PARSE(4), E_CORE_ERROR(16)
24 = E_NOTICE(8), E_CORE_ERROR(16)
25 = E_ERROR(1), E_NOTICE(8), E_CORE_ERROR(16)
26 = E_WARNING(2), E_NOTICE(8), E_CORE_ERROR(16)
27 = E_ERROR(1), E_WARNING(2), E_NOTICE(8), E_CORE_ERROR(16)
28 = E_PARSE(4), E_NOTICE(8), E_CORE_ERROR(16)
29 = E_ERROR(1), E_PARSE(4), E_NOTICE(8), E_CORE_ERROR(16)
30 = E_WARNING(2), E_PARSE(4), E_NOTICE(8), E_CORE_ERROR(16)
31 = E_ERROR(1), E_WARNING(2), E_PARSE(4), E_NOTICE(8), E_CORE_ERROR(16),


If you are still using mysql_ functions, STOP! Use mysqli_ or PDO. The longer you leave it the more you will have to rewrite.

Donations gratefully received






moon.png

|baaGrid| easy data tables - and more
|baaChart| easy line, column and pie charts

#20 Zane

Zane
  • Administrators
  • Advanced Member
  • 4,134 posts

Posted 31 October 2006 - 01:05 AM

I'll have to study the pattern of that tomrrow...

Thanks a lot Barrand, I learned a lot in the last...while.

@roopurt too

I'm definitely putting this thread in the Repository when it's all said and done.
Some very useful information here.

btn_donate_SM.gif Want to thank me? Contribute to my PayPal piggy-bank
 

172938.png




0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users