FireFox! The PHP Forum Loans and Credit
Panama Web Design for Hire Free Insurance Quotes!
Web Hosting Advertise Here $10 a Month Designer Children
Never Pay Taxes Again HGH Domain name registration
Web Hosting and Dedicated Servers Insurance Affordable web-hosting


HomeWatched TopicsRegisterSearchDirectory
FAQMemberlistUsergroupsLog inStoresItemsBank
Google

Reply to topic Page 1 of 1
Bits and bitwise operators - I
Message  

Reply with quote
Post Bits and bitwise operators - I 
This tutorial will attempt to teach you what bits are, how binary arithmetic works, what bitwise operators are and how they work.

Numeral systems
Normally when you think of numbers you might be thinking about the decimal system (BASE 10) which is a system consisting of 10 digits (0, 1, 2, 3, 4, 5, 6, 7, 8, 9), but in fact there exists several numeral systems. Another system you most likely are familiar with, is the sexagesimal system (BASE 60). If you do not think so, then just take a look at any digital watch. BASE 60 is commonly used in measure of time and in geographic coordinates. In this tutorial I am not going to talk about either BASE 10 or BASE 60, but I am going to talk about BASE 2, or "the binary numeral system".

The binary numeral system
The binary system consists of 2 digits (0, 1) and it is with them you count. In order to be able to count in binary, you will need to learn some binary arithmetic.

Binary arithmetic
Think of a random number (in decimal). For now we will take 143. 143, that is 1 hundred(s), 4 ten(s) and 3 one(s). It could also be displayed as:
(1*102) + (4*101) + (3*100) = 143

In binary it is the exact same thing, except that it only deals with 2 digits. Let's try to get 143 in binary: 10001111, and "in math":
10001111 = (1*27) + (0*26) + (0*25) + (0*24) + (1*23) + (1*22) + (1*21) + (1*20) = 143

If we break it down we will get:
1 - (1*27) = (1*128) = 128
0 - (0*26) = (0*64) = 0 (I suppose you've got the point about that now)
0 - (0*32) = 0
0 - (0*16) = 0
1 - (1*Cool = 8
1 - (1*4) = 4
1 - (1*2) = 2
1 - (1*1) = 1
That gives us 128+8+4+2+1 and that gives 143

Bits and bytes
What is a bit? A bit is a representation of 1 or 0, ON or OFF, true or false. A byte is simply just made by 8 bits, which makes its highest value 255. When talking about sizes 1 byte is equal to 1 character. When you have a lot of bytes you might see KB, MB, GB etc. KB can either mean 1000 bytes or 1024 bytes depending on if the SI prefix or the Binary prefix standards from IEC 60027-2 (which then really should be displayed as KiB, MiB, GiB etc.) is used.

Now let's take an example byte:

1 Byte (= 8 bits) 128 64 32 16 8 4 2 1  
0 0 1 1 1 0 0 1 = 57

The first row represents 2 to the power of 7, 6, 4, 3, 2, 1 and 0, and the second row represents the bits state. The above byte has the value 57.

In ASCII there are the standard set from 1-127. As requirement for additional characters came, a new set Extended ASCII (also sometimes refered to as High ASCII) which goes from 128-255. The above bit would represent the character 9 (nine). See: ASCII table (external), Extended ASCII table (external). Later Unicode emerged as even more characters was needed.

Source: http://www.phpfreaks.com/tutorials/151/2.php

View user's profile Send private message

Reply with quote
Post  
Bitwise operators
Here is a list of all the bitwise operators. As it will only work with valid integers you can, just to be sure, either use typecasting or put it in the intval() function. Example:

PHP Example: (!)<?php
// using typecasting
$c = (int)$a & (int)$b;

// using intval()
$c = intval($a) & intval($b);
?>

Also note that the bitwise operators should not be confused with the logical operators.

A list of the bitwise operators Example: Name: Result:
$a & $b AND Bits that are set in both $a and $b are set.
$a | $b OR Bits that are set in either $a or $b are set.

Source: http://www.phpfreaks.com/tutorials/151/5.php
$a ^ $b XOR Bits that are set in $a or $b, but not both are set.
~ $a NOT Bits that are not in $a set are set, and vice versa.
$a >> $b Shift left Shift the bits of $a $b steps to the left (each step means "multiply by two")
$a << $b Shift right Shift the bits of $a $b steps to the right (each step means "divide by two")

Now follows examples and explanations of the different types of bitwise operators.

AND
AND takes two decimal versions of binary values and return a new decimal value. Here is an example:

PHP Example: (!)<?php
$a = 20;
$b = 36;
echo $a & $b; // outputs: 4
?>

Now why does this output 4? Let's try to put it in a table:

20 & 36   128 64 32 16 8 4 2 1  
$a 0 0 0 1 0 1 0 0 = 20
$b 0 0 1 0 0 1 0 0 = 57
New value 0 0 0 0 0 1 0 0 = 4

As you see, the only bit they share is 4, so that is the value returned. Pretty simple, eh?

OR
OR also takes two decimal versions of binary values and return a new decimal representation of a binary value. Example:

PHP Example: (!)<?php
$a = 20;
$b = 36;
echo $a | $b; // outputs: 52
?>
20 | 36   128 64 32 16 8 4 2 1  
$a 0 0 0 1 0 1 0 0 = 20
$b 0 0 1 0 0 1 0 0 = 57
New value 0 0 1 1 0 1 0 0 = 52

OR takes bits that are either set in $a or $b and sets them all in the returned value. That results in bit 4, 16 and 32 being set which then results in 52.

XOR
XOR is like OR, only that it is the ones which are exclusively set. Example (same numbers as before):

PHP Example: (!)<?php
$a = 20;
$b = 36;
echo $a ^ $b; // outputs: 48
?>
20 ^ 36   128 64 32 16 8 4 2 1  
$a 0 0 0 1 0 1 0 0 = 20
$b 0 0 1 0 0 1 0 0 = 57
New value 0 0 1 1 0 0 0 0 = 48

As you can see, 4 is set on both, so it will not be set, but 32 is set in $b and 16 is set in $a (and no other) which means that both of them will be set, and as 16+32=48 it will return 48.

NOT
NOT turns sets on bits off and off bits on. You could say that it reverses the bit. NOT is always used with some other operator. Example:

PHP Example: (!)<?php
$a = 20;
$b = 36;
echo ~$a & $b; // outputs: 32
?>

This finds out what bits that are NOT set in $a and what bits that are set in $b.

~20 & 36   128 64 32 16 8 4 2 1  
$a 0 0 0 1 0 1 0 0 = 20
$b 0 0 1 0 0 1 0 0 = 57
New value 0 0 0 1 0 0 0 0 = 32

The above one might be a little tricky. First it reverses 20 (00010100) which results in 11101011, then the AND operator is used on it and the only "shared" bit is 32 which is in both ~$a and $b.

Note that you don't have to use AND, you can use all the other ones as well.

Left shift
Left shift shifts all bits X positions left (one shift is also equal to multiply with 2). Example:

PHP Example: (!)<?php
$a = 20;
echo $a << 1; // outputs: 40
?>
20 << 1   128 64 32 16 8 4 2 1  
$a 0 0 0 1 0 1 0 0 = 20
New value 0 0 1 0 1 0 0 0 = 40

As you see all the on bits are moved to the 1 to the left, also resulting in a multiplication by 2. New value = 40.

Right shift
Right shift works the same way except that the bits are shifted right instead of left (also equal to divide by 2). Example:

PHP Example: (!)<?php
$a = 20;
echo $a >> 1; // outputs: 10
?>
20 >> 1   128 64 32 16 8 4 2 1  
$a 0 0 0 1 0 1 0 0 = 20
New value 0 0 0 0 1 0 1 0 = 40

As you see all the on bits are moved to the 1 to the right, also resulting in a division by 2. New value = 10.

Implementation and usage
One thing you can use this for could be permissions systems. Imagine a forum system with the following permission flags: can login (is not banned), can start topic, can reply to topic, is mod, is admin:

PHP Example: (!)<?php
// First we define our permission flags:
define('CAN_LOGIN',            1);
define('CAN_START_TOPIC',    2);
define('CAN_REPLY',            4);
define('IS_MOD',            ;
define('IS_ADMIN',            16);

// We have three users: John who is just regular user who may login, post and reply, George who is a moderator as well, and Jim who is banned (as he does not have the CAN_LOGIN flag):
$john    = 7; // CAN_LOGIN | CAN_START_TOPIC | CAN_REPLY
$george = 15; // CAN_LOGIN | CAN_START_TOPIC | CAN_REPLY | IS_MOD
$jim    = 0; // *nothing*

// We are at the login screen. All three users are trying to login. This checks if the bits set for them shares the bits set in CAN_LOGIN:
if($john & CAN_LOGIN)
{
    echo "John can loginn";
}
else {
    echo "John cannot loginn";
}

if($george & CAN_LOGIN)
{
    echo "George can loginn";
}
else {
    echo "George cannot loginn";
}

if($jim & CAN_LOGIN)
{
    echo "Jim can loginn";
}
else {
    echo "Jim cannot loginn";
}

// Now both John and George are trying to trying to enter a special control panel for administrators only:
if($john & IS_ADMIN)
{
    echo "John can enter admin control paneln";
}
else {
    echo "John cannot enter admin control paneln";
}

if($george & IS_ADMIN)
{
    echo "George can enter admin control paneln";
}
else {
    echo "George cannot enter admin control paneln";
}

// George was supposed to recently being promoted to administrator, but his manager apparently forgot to grant him new permissions. George calls him and the manager updates George's permissions:
$george = $george | IS_ADMIN;

// George tries again:
if($george & IS_ADMIN)
{
    echo "George can enter admin control paneln";
}
else {
    echo "George cannot enter admin control paneln";
}

// John creates a new topic:
if($john & CAN_START_TOPIC)
{
    echo "John can start a new topicn";
}
else {
    echo "John cannot start a new topicn";
}

// George thinks John is starting all sorts of wierd topics, so he decides (with his new admin powers) that John's CAN_START_TOPIC permission flag should be revoked:
$john = $john & ~CAN_START_TOPIC ;

// Now John tries to start a new topic again:
if($john & CAN_START_TOPIC)
{
    echo "John can start a new topicn";
}
else {
    echo "John cannot start a new topicn";
}

/* This script will output:
John can login
George can login
Jim cannot login
John cannot enter admin control panel
George cannot enter admin control panel
George can enter admin control panel
John can start a new topic
John cannot start a new topic
*/
?>
Edit: There is apparently some display error with the code. There is supposed to be a linefeed at the end of each echo, but this is just a minor issue that won't really have significant effect.

View user's profile Send private message
Display posts from previous:
Reply to topic Page 1 of 1
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
  



Google

FireFox! The PHP Forum Loans and Credit
Panama Web Design for Hire Free Insurance Quotes!
Web Hosting Advertise Here $10 a Month Designer Children
Never Pay Taxes Again HGH Domain name registration
Web Hosting and Dedicated Servers Insurance Affordable web-hosting


Web Design by PlatinumShore.com & Web Hosting by TradeWebHosting.com