note 50299 added to language.operators.bitwise
| From: | icy at digitalitcc dot com | Date: | Thu, 24 Feb 2005 07:24:29 +0000 |
| Subject: | note 50299 added to language.operators.bitwise | ||
| Groups: | php.notes | ||
| Request: | Send a blank email to php-notes+get-85469@lists.php.net to get a copy of this message | ||
Say... you really want to have say... more than 31 bits available to you in your happy bitmask. And
you don't want to use floats. So, one solution would to have an array of bitmasks, that are
accessed through some kind of interface.
Here is my solution for this: A class to store an array of integers being the bitmasks. It can hold
up to 66571993087 bits, and frees up unused bitmasks when there are no bits being stored in them.
<?php
/*
Infinite* bits and bit handling in general.
*Not infinite, sorry.
Perceivably, the only limit to the bitmask class in storing bits would be
the maximum limit of the index number, on 32 bit integer systems 2^31 - 1,
so 2^31 * 31 - 1 = 66571993087 bits, assuming floats are 64 bit or something.
I'm sure that's enough enough bits for anything.. I hope :D.
*/
DEFINE('INTEGER_LENGTH',31); // Stupid signed bit.
class bitmask
{
protected $bitmask = array();
public function set( $bit ) // Set some bit
{
$key = (int) ($bit / INTEGER_LENGTH);
$bit = (int) fmod($bit,INTEGER_LENGTH);
$this->bitmask[$key] |= 1 << $bit;
}
public function remove( $bit ) // Remove some bit
{
$key = (int) ($bit / INTEGER_LENGTH);
$bit = (int) fmod($bit,INTEGER_LENGTH);
$this->bitmask[$key] &= ~ (1 << $bit);
if(!$this->bitmask[$key])
unset($this->bitmask[$key]);
}
public function toggle( $bit ) // Toggle some bit
{
$key = (int) ($bit / INTEGER_LENGTH);
$bit = (int) fmod($bit,INTEGER_LENGTH);
$this->bitmask[$key] ^= 1 << $bit;
if(!$this->bitmask[$key])
unset($this->bitmask[$key]);
}
public function read( $bit ) // Read some bit
{
$key = (int) ($bit / INTEGER_LENGTH);
$bit = (int) fmod($bit,INTEGER_LENGTH);
return $this->bitmask[$key] & (1 << $bit);
}
public function stringin($string) // Read a string of bits that can be up to the maximum amount of
bits long.
{
$this->bitmask = array();
$array = str_split( strrev($string), INTEGER_LENGTH );
foreach( $array as $key => $value )
{
if($value = bindec(strrev($value)))
$this->bitmask[$key] = $value;
}
}
public function stringout() // Print out a string of your nice little bits
{
$string = "";
$keys = array_keys($this->bitmask);
sort($keys, SORT_NUMERIC);
for($i = array_pop($keys);$i >= 0;$i--)
{
if($this->bitmask[$i])
$string .= sprintf("%0" . INTEGER_LENGTH . "b",$this->bitmask[$i]);
}
return $string;
}
public function clear() // Purge!
{
$this->bitmask = array();
}
public function debug() // See what's going on in your bitmask array
{
var_dump($this->bitmask);
}
}
?>
It treats a positive integer input as a bit, so you don't have to deal with the powers of 2
yourself.
<?php
$bitmask = new bitmask();
$bitmask->set(8979879); // Whatever
$bitmask->set(888);
if($bitmask->read(888))
print 'Happy!\n';
$bitmask->toggle(39393); // Yadda yadda
$bitmask->remove(888);
$bitmask->debug();
$bitmask->stringin("100101000101001000101010010101010
00000001000001");
print $bitmask->stringout() . "\n";
$bitmask->debug();
$bitmask->clear();
$bitmask->debug();
?>
Would produce:
Happy!
array(2) {
[289673]=>
int(65536)
[1270]=>
int(8388608)
}
0000000000000001001010001010010001010100101010100
0000001000001
array(2) {
[0]=>
int(355106881)
[1]=>
int(37970)
}
array(0) {
}
----
Manual Page -- http://www.php.net/manual/en/language.operators.bitwise.php
Edit -- http://master.php.net/manage/user-notes.php?action=edit+50299
Delete: added to the manual -- http://master.php.net/manage/user-notes.php?action=delete+50299&report=yes&reason=added+to+the+manual
Delete: bad code -- http://master.php.net/manage/user-notes.php?action=delete+50299&report=yes&reason=bad+code
Delete: spam -- http://master.php.net/manage/user-notes.php?action=delete+50299&report=yes&reason=spam
Delete: useless -- http://master.php.net/manage/user-notes.php?action=delete+50299&report=yes&reason=useless
Delete: other reasons -- http://master.php.net/manage/user-notes.php?action=delete+50299&report=yes
Reject -- http://master.php.net/manage/user-notes.php?action=reject+50299&report=yes
Search -- http://master.php.net/manage/user-notes.php