Zane Posted October 29, 2006 Share Posted October 29, 2006 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 Link to comment https://forums.phpfreaks.com/topic/25503-bitwise-operators/ Share on other sites More sharing options...
ignace Posted October 29, 2006 Share Posted October 29, 2006 well finally someone with zero replies and a question i can answer :Dusing bitwise operator with variables:[code]<?php# the bitwise operator$value1 = "ignace";$value2 &= $value1;echo $value2;?>[/code]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:[code]<?php$value1 = "ignace";function insertIt(&$value){ $value = "not ignace";}insertIt($value1);echo $value1; # output: not ignace?>[/code] Link to comment https://forums.phpfreaks.com/topic/25503-bitwise-operators/#findComment-116359 Share on other sites More sharing options...
Zane Posted October 29, 2006 Author Share Posted October 29, 2006 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 Link to comment https://forums.phpfreaks.com/topic/25503-bitwise-operators/#findComment-116363 Share on other sites More sharing options...
Barand Posted October 29, 2006 Share Posted October 29, 2006 Bitwise operators work on the individual bits in a value (as it says on the tin)[b]Bitwise 'AND'[/b]$a & $bbits in the result are set only if the corresponding bit is set in both $a and $b[code]$a = 7 0111$b = 13 1101$a & $b 0101 = 5[/code]So you can use it to turn bits 'OFF' in $a by ANDing with a value with a zero in that position++++++++++++++++++++++++++++++++++++++++++++++[b]Bitwise 'OR'[/b]$a | $bbits in the result are set if 1 or both the correspondings bit set $a and $b[code]$a = 7 0111$b = 8 1000$a | $b 1111 = 15[/code]So you can use it to turn bits 'ON' in $a by ORing with a value with a 1 in that position++++++++++++++++++++++++++++++++++++++++++++++++[b]Exclusive OR (XOR)[/b]$a ^ $bbits in the result are set if 1 or other but not both the correspondings bit set $a and $b[code]$a = 7 0111$b = 13 1101$a ^ $b 1010 = 6[/code]Note the process is reversible by repeating the operation[code]]$a = 6 1010$b = 13 1101$a ^ $b 0111 = 7[/code]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.+++++++++++++++++++++++++++++++++++++++++++++++++++++[b]NOT[/b]~ $aSimply reverses all the bits.[code]$a = 9 1001~$a 0110 = 6[/code]++++++++++++++++++++++++++++++++++++++++++++++++++++++[b]Left shift[/b]$a << $bMoves all the bits to left and pads with 0 at right[code]$a = 4 0100$a << 1 1000 = 8 quick multiply by 2[/code]++++++++++++++++++++++++++++++++++++++++++++++++++++++++[b]Right shift[/b]$a >> $bMoves all the bits to right and pads with 0 at left[code]$a = 4 0100$a >> 1 0010 = 2 quick divide by 2[/code]++++++++++++++++++++++++++++++++++++++++++++++++++++++++Useful used in combination. Suppose you have a color value of 0x336699 and you want the green component value[code]]<?php$color = 0x336699;$green = ($color >> 8) & 0xFF; echo dechex($green); // --> 0x66?>[/code] Link to comment https://forums.phpfreaks.com/topic/25503-bitwise-operators/#findComment-116391 Share on other sites More sharing options...
Zane Posted October 30, 2006 Author Share Posted October 30, 2006 WowI completely understand how it worksbut I have no clue why I would use it now.I can't spot the convenience of itThank you for the extensive examples though BarrandI'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 Link to comment https://forums.phpfreaks.com/topic/25503-bitwise-operators/#findComment-116869 Share on other sites More sharing options...
roopurt18 Posted October 30, 2006 Share Posted October 30, 2006 User group permissions:http://www.phpfreaks.com/forums/index.php/topic,110890.0.html Link to comment https://forums.phpfreaks.com/topic/25503-bitwise-operators/#findComment-116872 Share on other sites More sharing options...
Zane Posted October 30, 2006 Author Share Posted October 30, 2006 In reference to this posthttp://www.phpfreaks.com/forums/index.php/topic,110890.msg450649.html#msg450649So to check my understanding..using as little jargon as possible.At the beginning you have NO permissions..meaning just thatthen say you want to allow them to delete a userDelete a user has it's own numeric ...hex..value..whateversay 0x00000064if I want to append that permissioin to the $perms variable I use the | operator?[code=php:0]$perms = $perms | 0x00000064[/code][color=teal]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[/color]and I validate it with the & operator?[code=php:0]if($perms & 0x00000064) //Can delete users[/code]Say I did it vice versa?[code=php:0]$perms = $perms & 0x00000064;if($perms | 0x00000064) //Then what[/code] Link to comment https://forums.phpfreaks.com/topic/25503-bitwise-operators/#findComment-116879 Share on other sites More sharing options...
roopurt18 Posted October 30, 2006 Share Posted October 30, 2006 [code]<?php$perms = $perms & 0x00000064;if($perms | 0x00000064) //Then what?>[/code][code]<?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 executesif($perms | 0x00000064)?>[/code]Doing it the [b]correct[/b] way:[code]<?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 evaluatesif($perms & 0x00000002)// later in the code, after $perms as been assigned more// $perms & 0x00000002 -> 0x0000BBC4 -> 0x00000000, so the body of the if DOES NOT evaluateif($perms & 0x00000002)?>[/code] Link to comment https://forums.phpfreaks.com/topic/25503-bitwise-operators/#findComment-116888 Share on other sites More sharing options...
Zane Posted October 30, 2006 Author Share Posted October 30, 2006 ReCap again...alrightI'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... 0x00000064Explain to me the way barand did, how the variable is changed.would zanesPerms be 0x00000192? or something else and whyI appreciate your help a lot Link to comment https://forums.phpfreaks.com/topic/25503-bitwise-operators/#findComment-116898 Share on other sites More sharing options...
Barand Posted October 30, 2006 Share Posted October 30, 2006 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 111111111111E_NOTICE 000000001000~E_NOTICE 111111110111 E_ALL & ~E_NOTICE 111111110111[/pre] Link to comment https://forums.phpfreaks.com/topic/25503-bitwise-operators/#findComment-116952 Share on other sites More sharing options...
roopurt18 Posted October 30, 2006 Share Posted October 30, 2006 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 1000You don't need 3 ones in your permission constant to specify 1 setting.So let's say you have the following:0x01 -> 0000 00010x02 -> 0000 00100x01 & 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 Link to comment https://forums.phpfreaks.com/topic/25503-bitwise-operators/#findComment-117002 Share on other sites More sharing options...
Zane Posted October 30, 2006 Author Share Posted October 30, 2006 Ok...it's making much more sense nowSo say I wanted to show all errors exceptE_CORE_WARNING - 32 bitsE_COMPILE_WARNING - 128 bitsE_USER_WARNING - 512 bitswould I say?in a non-constant sense[code]$showErrors = 11111111111; //E_ALL$showErrors = $showErrors & ~100000 // ~E_CORE_WARNING$showErrors = $showErrors & ~10000000 // E_COMPILE_WARNING$showErrors = $showErrors & ~100000000 //E_USER_WARNINGerror_reporting($showErrors);[/code]or another quesitonwould $showErrorsthen equal?10101011111 Link to comment https://forums.phpfreaks.com/topic/25503-bitwise-operators/#findComment-117032 Share on other sites More sharing options...
Barand Posted October 30, 2006 Share Posted October 30, 2006 Yes.To verify[code]<?php$level = E_ALL & ~(E_CORE_WARNING | E_COMPILE_WARNING | E_USER_WARNING) ;echo decbin($level); ?>[/code]--> 10101011111 Link to comment https://forums.phpfreaks.com/topic/25503-bitwise-operators/#findComment-117038 Share on other sites More sharing options...
Zane Posted October 31, 2006 Author Share Posted October 31, 2006 OMG I learned something!thanks so much guysNow 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 Consideringecho decbin(E_ALL & ~(E_CORE_WARNING | E_COMPILE_WARNING | E_USER_WARNING));returns 10101011111echo decbin(E_ALL | ~(E_CORE_WARNING & E_COMPILE_WARNING & E_USER_WARNING));should return.....---time goes by-[code]E_CORE_WARNING (0000100000) & E_COMPILE_WARNING(0010000000) & E_USER_WARNING(1000000000)(0000100000 & 0010000000 & 1000000000) = 0000000000~0000000000 = 1111111111E_ALL(1111111111) & 1111111111 = 0000000000[/code]Furthermore...say I wenterror_reporting(E_ALL >> 5)translating to.......1111111111 -> 0000011111 -> 3131 translating to E_CORE_ERROR I guess since 32 hasn't been reached yet...right? Link to comment https://forums.phpfreaks.com/topic/25503-bitwise-operators/#findComment-117047 Share on other sites More sharing options...
Barand Posted October 31, 2006 Share Posted October 31, 2006 No31 is all these1 E_ERROR 2 E_WARNING 4 E_PARSE 8 E_NOTICE 16 E_CORE_ERROR Link to comment https://forums.phpfreaks.com/topic/25503-bitwise-operators/#findComment-117059 Share on other sites More sharing options...
Zane Posted October 31, 2006 Author Share Posted October 31, 2006 So is that true for all numbers17 through 31here I am at another interesting point.say I wanted to test such a questionwith a loop[code=php:0]for($i=17;$i<32;$i++) { if(decbin(31) | decbin($i)) echo "$i is all of them";}[/code]would that work? Link to comment https://forums.phpfreaks.com/topic/25503-bitwise-operators/#findComment-117062 Share on other sites More sharing options...
Barand Posted October 31, 2006 Share Posted October 31, 2006 if it was your intention to print[code]17 is all of them18 is all of them19 is all of them20 is all of them21 is all of them22 is all of them23 is all of them24 is all of them25 is all of them26 is all of them27 is all of them28 is all of them29 is all of them30 is all of them31 is all of them[/code]then it works ;) Link to comment https://forums.phpfreaks.com/topic/25503-bitwise-operators/#findComment-117064 Share on other sites More sharing options...
Zane Posted October 31, 2006 Author Share Posted October 31, 2006 eh..I was just wondering since the numbers 17 through 31are both greater than 16 and NOT a power of twothat they would all be classified as ALL of these----------------------1 E_ERROR 2 E_WARNING 4 E_PARSE 8 E_NOTICE 16 E_CORE_ERRORI'm assuming they areI just wrote the loop wrong...that IF will always return true regardless I just realized...unless the result is 0 Link to comment https://forums.phpfreaks.com/topic/25503-bitwise-operators/#findComment-117068 Share on other sites More sharing options...
Barand Posted October 31, 2006 Share Posted October 31, 2006 try[code]<?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>';?>[/code]EDIT by zanusEdit by Barand to show results with bit valuesreturns[quote][nobbc]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),[/nobbc][/quote] Link to comment https://forums.phpfreaks.com/topic/25503-bitwise-operators/#findComment-117073 Share on other sites More sharing options...
Zane Posted October 31, 2006 Author Share Posted October 31, 2006 I'll have to study the pattern of that tomrrow...Thanks a lot Barrand, I learned a lot in the last...while.@roopurt tooI'm definitely putting this thread in the Repository when it's all said and done.Some very useful information here. Link to comment https://forums.phpfreaks.com/topic/25503-bitwise-operators/#findComment-117076 Share on other sites More sharing options...
Zane Posted October 31, 2006 Author Share Posted October 31, 2006 oh ok..I get itI can't exactly explain why I get it, but i reminds me of the same wayCHMOD permissions work..but more extended Link to comment https://forums.phpfreaks.com/topic/25503-bitwise-operators/#findComment-117428 Share on other sites More sharing options...
Barand Posted October 31, 2006 Share Posted October 31, 2006 [quote author=zanus link=topic=113143.msg460676#msg460676 date=1162319174]oh ok..I get itI can't exactly explain why I get it, but i reminds me of the same wayCHMOD permissions work..but more extended[/quote]Yes, it's just the same Link to comment https://forums.phpfreaks.com/topic/25503-bitwise-operators/#findComment-117444 Share on other sites More sharing options...
roopurt18 Posted October 31, 2006 Share Posted October 31, 2006 It [i]is[/i] the way [b]chmod[/b] works:[b]chmod[/b] gives you four columns, each of which can be a bit combination of the following:4 : 01002 : 00101 : 0001Since the highest bit possible is the (counting from the right) 3rd bit, we can ignore the 4th bit and drop it.4 : 1002 : 0101 : 001Now, [b]chmod[/b] has 4 possible settings, each setting is a combination of those 3 bits. So all total we need [i]at least[/i] 4 * 3 = [b]12[/b] bits to represent a [b]chmod[/b] setting.chmod columns:[code]SUI Owner Group Others000 000 000 000[/code][b]Counting Problems[/b][i]Q:[/i] How many combinations exist for each [b]chmod[/b] column?[i]A:[/i] 3 binary digits, each with 2 possible (0 or 1) values minus the number of impossible values (000): 2 * 2 * 2 - 1 = 7[i]Q:[/i] How many possible [b]chmod[/b] permissions exist?[i]A:[/i] Our answer from above multiplied by the number of columns (4), or: 28 Link to comment https://forums.phpfreaks.com/topic/25503-bitwise-operators/#findComment-117454 Share on other sites More sharing options...
roopurt18 Posted October 31, 2006 Share Posted October 31, 2006 An extension to my reply above. When you're using bits to represent settings you're packing them into a variable. That variable might be 16, 32, 64, etc. bits in length. The size of that variable determines how many preferences or permissions you can pack in there.For instance, a 32-bit variable can represent 32 permissions with on / off settings.If you have a preference that is more than on / off, maybe it's: very low, low, avg, high, very high. That's 5 settings for one permission / preference. How many bits are necessary to store 5 unique combinations? The answer is 3 bits:001 - very low010 - low011 - avg100 - high101 - very highNotice that we didn't use the values 000, 110, or 111.Going back to our 32-bit number, if we were storing the previous preference / permission, 3 of the 32 bits would be taken by that preference. This leaves us with 29 more bits to work with; we could store 29 more on / off preferences [b]or[/b] maybe 23 more on / off preferences and another preference that requires 6 bits (23 + 6 = 29).As for how we would go about storing and retrieving such a preference:[code]<?phpdefine( 'PNAME_VLOW', 0x01 );define( 'PNAME_LOW', 0x02 );define( 'PNAME_AVG', 0x03 );define( 'PNAME_HIGH', 0x04 );define( 'PNAME_VHIGH', 0x05 );define( 'PNAME_ALL', 0x07 );$prefs = 0x00; // Set initial preferences// A lot of code that modifies the value in $prefs// Now determine which of PNAME the user has permission to doswitch( $prefs & PNAME_ALL ){ case PNAME_VLOW: // very low break; case PNAME_LOW: // low break; case PNAME_AVG: // average break; // And so on...}?>[/code]Notice now that instead of checking if the bit is turned on (Using $prefs & PNAME_const), we're checking which out of [b]all[/b] the bits for the preference are on [b]and[/b] which value they're equal to. Link to comment https://forums.phpfreaks.com/topic/25503-bitwise-operators/#findComment-117462 Share on other sites More sharing options...
Recommended Posts