What is the easiest way to make bitwise operations(OR, AND)

PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!

Moderator: General Moderators

Post Reply
User avatar
raghavan20
DevNet Resident
Posts: 1451
Joined: Sat Jun 11, 2005 6:57 am
Location: London, UK
Contact:

What is the easiest way to make bitwise operations(OR, AND)

Post by raghavan20 »

I have got a few 32-bits chunks which have to XORed.
This ^ operator does not seem to work.
This is what I tried...

Code: Select all

echo "<br />111 ^ 101:".(111 ^ 101);
		echo "<br />011 ^ 101:".(011 ^ 101);
		echo "<br />111 ^ 111:".(111 ^ 111);
		echo "<br />000 ^ 101:".(000 ^ 101);
Output:

Code: Select all

111 ^ 101:10 //should be 010
011 ^ 101:108 //should be 110
111 ^ 111:0 //should be 000
000 ^ 101:101 //should be 101
You can see that's not the intended output. I want the output to be in bits.
I can write a function but not really want to, if there is already a PHP function which can do it.
User avatar
feyd
Neighborhood Spidermoddy
Posts: 31559
Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA

Post by feyd »

you're giving it decimals so the xor will be off until you convert the bits to binary forms and back for display..
User avatar
raghavan20
DevNet Resident
Posts: 1451
Joined: Sat Jun 11, 2005 6:57 am
Location: London, UK
Contact:

Post by raghavan20 »

Code:


111 ^ 101:10 //should be 010
011 ^ 101:108 //should be 110
111 ^ 111:0 //should be 000
000 ^ 101:101 //should be 101


I dont know what you are saying cos I am supplying input as binary.
111, 101,011....all are binary strings.
User avatar
raghavan20
DevNet Resident
Posts: 1451
Joined: Sat Jun 11, 2005 6:57 am
Location: London, UK
Contact:

Post by raghavan20 »

Interestingly I now see a problem with the left shift operator the way it works
It assumes that it gets the input as decimal and converts it into binary and performs the left shift and finally displays the result in decimal again.

Code: Select all

for ex:
input: 101
left shifted << 1
expected output: 010
original output: 202
Is there a bitwise operator which operates on binary not on decimals???
User avatar
Chris Corbyn
Breakbeat Nuttzer
Posts: 13098
Joined: Wed Mar 24, 2004 7:57 am
Location: Melbourne, Australia

Post by Chris Corbyn »

I'll try to explain:

PHP does all calculations in binary, but we code it in decimal... that's normal. The numbers we type in (e.g., 12, 32, 110, 120 etc..) are all assumed to be decimal unless we say otherwise. PHP outputs all numbers in decimal too.

Binary doesn't neccessarily have to be one's and zero's, it's just on and off states (the accepted is to represnt this with ones and zeros however).

Using the bitwise operators in PHP works as expected it's just that you need to know what the decimal values are AND if you don't know that there's the function decbin() and bindec() to convert between the two :)

So

Code: Select all

echo 10 ^ 5; //Binary equivalent is:   1010 XOR 101   (15)
Why?

Code: Select all

16   |   8   |   4   |   2   |  1   |    Decimal
-------------------------------------------------------
             1        0       1      0               10
                      1       0      1                5

Bits in 10 that are NOT in 5 =>
   16   |   8   |   4  |    2  |   1      
---------------------------------------
            1       0       1      0    

Bits in 5 that are NOT in 10 =>
   16  |   8   |   4   |   2  |   1      
-----------------------------------
                   1       0      1   

Which gives =>
  16   |   8   |   4  |   2   |   1   |   Decimal
----------------------------------------------------
          1        1       1      1           15
If you wanted to do that in a more clearly binary sense:

Code: Select all

echo bindec(1010) ^ bindec(101); //15
Hope that helps :)
User avatar
raghavan20
DevNet Resident
Posts: 1451
Joined: Sat Jun 11, 2005 6:57 am
Location: London, UK
Contact:

Post by raghavan20 »

thanks d11wtq for taking the pain to draw the example. I understood it in the first line itself.
the last function you have
bindec(1010) ^ bindec(101) is very useful; I'll use this in my code.
I think the same has to be done for bitwise shifting as well
like bindec(1010) << 1 to get 0100; alright, not to forget that the output shd be converted bk to binary
so it can now be written as
decbin(bindec(1010) << 1)
User avatar
feyd
Neighborhood Spidermoddy
Posts: 31559
Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA

Post by feyd »

uh.. bindec(1010) << 1 isn't 0100 (4) it's 10100 (20)
User avatar
raghavan20
DevNet Resident
Posts: 1451
Joined: Sat Jun 11, 2005 6:57 am
Location: London, UK
Contact:

Post by raghavan20 »

why is that??/
when I just supply four bits as input how can it move it as the fifth bit.
User avatar
onion2k
Jedi Mod
Posts: 5263
Joined: Tue Dec 21, 2004 5:03 pm
Location: usrlab.com

Post by onion2k »

The easiest way is to use my functions:

Code: Select all

function setbit($val, $bit) {
	if (readbit($val, $bit)) return $val;
	return $val += '0x'.dechex(1<<($bit-1));
}

function clearbit($val, $bit) {
	if (!readbit($val, $bit)) return $val;
	return $val^(0+('0x'.dechex(1<<($bit-1))));
}

function readbit($val, $bit) {
	return ($val&(0+('0x'.dechex(1<<($bit-1)))))?'1':'0';
}
readbit() returns the value of a bit in a value .. setbit() sets it to 'on', clearbit() sets it to 'off'.
User avatar
feyd
Neighborhood Spidermoddy
Posts: 31559
Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA

Post by feyd »

that seems like a lot of extra math and conversion that isn't really needed onion2k..

note this will only work for 32 bit integers

Code: Select all

function setBit($val,$bit) {
  return $val | (1 << $bit);
}

function clearBit($val,$bit) {
  return $val & ~(1 << $bit );
}

function readBit($val,$bit) {
  return (bool)($val & (1 << $bit));
}
now.. if you want arbitrary length integers use http://php.net/gmp
User avatar
raghavan20
DevNet Resident
Posts: 1451
Joined: Sat Jun 11, 2005 6:57 am
Location: London, UK
Contact:

Post by raghavan20 »

Thanks for those functions.
But you did not tell me why it produces
10100 instead of 0100
when operated on 1010, left shifting by 1.

1. does it assume the binary to be 32-bit inputs???
2. why is that in PHP all the functions expect decimal input rather than binary inputs??? Is there any logical reason for that???
User avatar
feyd
Neighborhood Spidermoddy
Posts: 31559
Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA

Post by feyd »

raghavan20 wrote:1. does it assume the binary to be 32-bit inputs???
integers are stored in signed 32-bit values within php. So yes.
raghavan20 wrote:2. why is that in PHP all the functions expect decimal input rather than binary inputs??? Is there any logical reason for that???
Why should they assume you are passing numbers in exploded binary view? Our world operates in 3 modes normally: Decimal, Octal, and Hex. To pass information in exploded binary would require processing time, plus there's no easy way to tell if a number is exploded binary or not in php.
Post Reply