note 62613 deleted from function.intval by cmb
| From: | cmb@php.net | Date: | Sun, 16 Feb 2020 13:51:48 +0000 |
| Subject: | note 62613 deleted from function.intval by cmb | ||
| References: | 1 | Groups: | php.notes |
| Request: | Send a blank email to php-notes+get-214151@lists.php.net to get a copy of this message | ||
Note Submitter: mkamerma at science dot uva dot nl
----
When you need to work with integer values that exceed maxint, the following functions may be of use
to you - they form a codec pair for integers of variable length rather than fixed length, encoded in
a byte as a 7 bit numberal with a 1 bit has-more flag, indicating that the next byte encodes a
higher order part of the same number still.
<?php
/* encode integer as 7bit with has-more bit numeral,
ordered lowest byte first. */
function encode_7bhm($int) {
if ($int==0) return chr(0); // shortcut
$ret = "";
while($int != 0) {
$high = floor($int / 128); // overflow for this round
$low = $int - ($high * 128); // 7 bit numeral
if ($int > 0) {
if ($high > 0) { $low = $low + 128; } // has-more flag
$ret .= chr($low); } //encode
$int = $high; // set overflow as next round's number
}
return $ret;
}
/* decode a 7bit with has-more bit numeral,
ordered lowest byte first. */
function decode_7bhm($hmb) {
$ret = 0;
$pos = 0;
$high = 1;
while($high == 1) {
$byte = ord(substr($hmb, $pos, 1));
$high = floor($byte/128); // gets has-more flag
$low = $byte - ($high*128);
$ret += $low * pow(128, $pos++); // decode
}
return $ret;
}
?>
This codec pair is also quite useful when needing to write ints to files, as this is a low-numeral
biased encoding: most of the time this will only require 8 or 16 bit rather than the 32 bits an int
will use in fixed-length encoding.
The encoding range:
1 byte - 0 through 128 (2^7)
2 bytes - 129 through 16,384 (2^14)
3 bytes - 16,385 through 2,097,152 (2^21)
4 bytes - 2,097,153 through 268,435,456 (2^28)
while indeed a 32 bit encoded variable length integer will be lower than maxint, rather than needing
a new 32 bit block to represent higher range only 8 more bits are required to represent this higher
number (for completeness the range of representation by bytes 5-8 are listed):
5 bytes - 268,435,457 through 34,359,738,368 (2^35)
6 bytes - 343,59,738,369 through 4,398,046,511,104 (2^42)
7 bytes - 4,398,046,511,105 through 562,949,953,421,312 (2^49)
8 bytes - 562,949,953,421,313 through 720,57,594,037,927,936 (2^56)
Also for completeness, the function to read a 7 bit with has-more bit from a filepointer:
<?php
// read a 7bhm numeral from file
function read_7bhm($fp) {
$bytestring = "";
$high = 1;
while($high==1) {
$byte = fread($fp, 1);
$high = floor(ord($byte)/128); // check for has-more bit
$bytestring .= $byte;
}
return decode_7bhm($bytestring); }
?>