note 50299 added to language.operators.bitwise

From: 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

« previous php.notes (#85469) next »