Memory App
 



Building memory bonds
Php  >     ZCE 5.3  |  Patterns  |  Modern Php Php   >   Operators   >   Bitwise

Our normal everyday numbering system is a BASE 10 system.

4768 = 4000 + 700 + 60 + 8 =

4 * 10 * 10 * 10 + 
    7 *  10 * 10 + 
      6 * 10 +
           8
The BASE 2 system has the same concept however it goes by 2's instead of 10s

45 = 32 + 8 + 4 + 1 = 

// 00101101
0 * 2 * 2 * 2 * 2 * 2 * 2 * 2 + 
    0 * 2 * 2 * 2 * 2 * 2 * 2 + 
    1 * 2 * 2 * 2 * 2 * 2 + 
        0 * 2 * 2 * 2 * 2 + 
        1 * 2 * 2 * 2 +
            1 * 2 * 2 +
            0 * 2 +
                1
A bit is a representation of 1 or 0. A byte is made up of 8 bits and the highest value of a byte is 255, which would mean every bit is set.

1 + 2 + 4 + 8 + 16 + 32 + 64 + 128 = 255

AND (&)

Bits that are set in both $a and $b are set

$a = 9;    // 8 + 1; 00001001
$b = 10; // 8 + 2; 00001010
echo $a & $b; // 8

$a = 36; // 32 + 4; 00100100
$b = 103; // 64 + 32 + 4 + 2 + 1; 01100111
echo $a & $b; // 36

OR (|)

Bits that are set in either $a or $b are set

$a = 9;    // 8 + 1; 00001001
$b = 10; // 8 + 2; 00001010
echo $a | $b; // 11

XOR (^)

Bits that are set in $a or $b but not both are set

$a = 9;    // 8 + 1; 00001001
$b = 10; // 8 + 2; 00001010
echo $a ^ $b; // 3

NOT (~)

The NOT operator wants to know what is set in $a but NOT set in $b

$a = 9;    // 8 + 1; 00001001
$b = 10; // 8 + 2; 00001010
echo $a & ~$b; // 1

$a = 9;    // 8 + 1; 00001001
$b = 10; // 8 + 2; 00001010
echo ~$a & $b; // 2

Shift (>>)

Shift the bits of $a $b steps

$a = 16; // 00010000
echo $a << 2; // 01000000 = 64

$a = 16; // 00010000
echo $a >> 2; // 00000100 = 4
It's interesting to note that these last two operations provide an easy (and very fast) way ofmultiplying integers by a power of two.

$a = 1; // 00000001
echo $a << 2; // 00000100 = 4

$a = 8; // 00001000
echo $a >> 2; // 00000010 = 2
Be aware that there are overflow and underflow scenarios that can yield unexpected results. For example, on a 32-bit machine, the following will happen

$a = 1; // 00000001
echo $a << 8; // 10000000 = 256
echo $a * pow(2, 8); // 256

$a = 1; // 00000001
echo $a << 64; // outputs 0, because all the bits have been shifted out of the integer value
echo $a * pow(2, 64); // 4294967296
Example of using bitwise operators (this is great if you have many classes of persmission for users)

$read = 1;
$write = 2;
$readwrite = 16;
$local_admin = 32;
$global_admin = 64;
 
$jim = 96;
$mike = 16;
 
if($mike & 32) {} // return 16
    // Mike is allowed to edit;

// being able to store all those in a single integer is VERY handy 
// instead of having to do something like

if($is_local_admin && $is_global_admin && $can_edit_articles && $can_view_articles) {}

Bitwise shift


<?php
//echo str_pad('', 25, '1'); // 1111111111111111111111111 // 25 of 1
//echo str_pad(1, 25, 1); // 1111111111111111111111111 // 25 of 1
//echo bindec('1111') >> 2; // 3 (0011)


// --- Shift function ---

//echo str_pad(decbin(bindec('1111') >> 2), 4, '0', STR_PAD_LEFT); // 0011

function shift($str, $i) {
    return str_pad(decbin(bindec($str) >> $i), strlen($str), '0', STR_PAD_LEFT);
}

//echo shift('1111', 2); // 0011
//echo shift('111111', 3); // 000111


// --- Shift function (starting from char) ---

function shift2($str, $i, $start=0) {

    if ($start > strlen($str)) return $str;
    if ($start < 0) return $str;
    
    $left = substr($str, 0, $start);
    $right = substr($str, $start, strlen($str));

    return $left . str_pad(decbin(bindec($right) >> $i), strlen($right), '0', STR_PAD_LEFT);
}

//echo shift2('11111', 2); // 00111
//echo shift2('11111', 2, 1); // 10011
//echo shift2('11111', 2, 2); // 11001
//echo shift2('11111', 2, 3); // 11100
//echo shift2('11111', 2, 4); // 11110
//echo shift2('11111', 2, 7); // 11111