Friday, January 15, 2010

PHP5: Bitwise Left Shift Goes in Cycle

Going through ZEND PHP Certification Study Guide I came across a bit confusing example. It says that bitwise left shift by 32 positions on integer value of 1 performed on 32-bit machine would give 0 as a result.


Reading through the guide I usually write small snippets of code to check things myself and remember them better. So I did this time. To my big surprise, the result was different from what I had read. Here is the code:

<?php
$x = 1;
echo $x << 32;
// outputs 1

I wanted to find out what was going on, so I tried:

<?php
$x = 1;
print ('PHP_INT_SIZE: ' . PHP_INT_SIZE . "\n");
$maxBits = PHP_INT_SIZE * 8;

$format = '%0' . $maxBits . "b\n";

for ($i = $maxBits - 1; $i <= $maxBits + 1; $i++ ) {
printf('x << ' . $i . ': ' . $format, $x << $i);
}

for ($i = $maxBits * 2 - 1; $i <= $maxBits * 2 + 1; $i++ ) {
printf('x << ' . $i . ': ' . $format, $x << $i);
}

And here is the result I got:

PHP_INT_SIZE: 4
x << 31: 10000000000000000000000000000000
x << 32: 00000000000000000000000000000001
x << 33: 00000000000000000000000000000010
x << 63: 10000000000000000000000000000000
x << 64: 00000000000000000000000000000001
x << 65: 00000000000000000000000000000010

That means that bitwise shifting left goes in cycle modulo architecture-defined-number-of-bits. On 32-bit machine shift left by 32 bits gives same result as no shift at all (32 % 32 = 0). Shift by 33 is same as shift by 1 (33 % 32 = 1).
But is it really true? How about shifting different value than 1? I tried to shift 2 and here is the result:

PHP_INT_SIZE: 4
x << 31: 00000000000000000000000000000000
x << 32: 00000000000000000000000000000010
x << 33: 00000000000000000000000000000100
x << 63: 00000000000000000000000000000000
x << 64: 00000000000000000000000000000010
x << 65: 00000000000000000000000000000100

I checked the results on Mac (PHP 5.2.6), Windows (PHP 5.3) and Linux (PHP 5.2.12) and they were identical. It looks like new language feature which wasn't present while the ZEND PHP Certification Study Guide has been created. Although the Bitwise Operators manual page warns: "Don't left shift in case it results to number longer than 32 bits."
It's for another discussion whether to use it or not. Anyway, I guess it's good to know.

No comments:

Post a Comment