PHP - How to base_convert() up to base 62 - php

I need a base_convert() function that works from base 2 up to base 62 but I'm missing the math I need to use, I know that due to the limitations of PHP I need to make use of bcmath, which is fine.
Functions like these convert a number to and from base 10 to another base up to 62, but I want to implement the same functionality of base_convert(), e.g.: a only one function that can convert between arbitrary bases.
I've found a function that seems to do this, but it gives me the feeling of having some redundant and slow code and I would like to tweak it a little bit if I knew German, which I don't. =(
Here is a more readable version of the function:
function bc_base_convert($value, $quellformat, $zielformat)
{
$vorrat = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
if (min($quellformat, $zielformat) < 2)
{
trigger_error('Bad Format min: 2', E_USER_ERROR);
}
if (max($quellformat, $zielformat) > strlen($vorrat))
{
trigger_error('Bad Format max: ' . strlen($vorrat), E_USER_ERROR);
}
$dezi = '0';
$level = 0;
$result = '';
$value = trim(strval($value), "\r\n\t +");
$vorzeichen = '-' === $value{0} ? '-' : '';
$value = ltrim($value, "-0");
$len = strlen($value);
for ($i = 0; $i < $len; $i++)
{
$wert = strpos($vorrat, $value{$len - 1 - $i});
if (FALSE === $wert)
{
trigger_error('Bad Char in input 1', E_USER_ERROR);
}
if ($wert >= $quellformat)
{
trigger_error('Bad Char in input 2', E_USER_ERROR);
}
$dezi = bcadd($dezi, bcmul(bcpow($quellformat, $i), $wert));
}
if (10 == $zielformat)
{
return $vorzeichen . $dezi; // abkürzung
}
while (1 !== bccomp(bcpow($zielformat, $level++), $dezi));
for ($i = $level - 2; $i >= 0; $i--)
{
$factor = bcpow($zielformat, $i);
$zahl = bcdiv($dezi, $factor, 0);
$dezi = bcmod($dezi, $factor);
$result .= $vorrat{$zahl};
}
$result = empty($result) ? '0' : $result;
return $vorzeichen . $result;
}
Can anyone explain me the above function or give me some lights on the process of direct conversion between arbitrary bases?

As of PHP 5.3.2 both bc_math and gmp now support bases up to 62, so you can just do:
echo gmp_strval(gmp_init($mynumber, $srcbase), $destbase);
or the bc_math equivalent.

Please dont ask me where i got it from, i just remeber that its based of some examples i found on the web...
function charset_base_convert ($numstring, $fromcharset, $tocharset) {
$frombase=strlen($fromcharset);
$tobase=strlen($tocharset);
$chars = $fromcharset;
$tostring = $tocharset;
$length = strlen($numstring);
$result = '';
for ($i = 0; $i < $length; $i++) {
$number[$i] = strpos($chars, $numstring{$i});
}
do {
$divide = 0;
$newlen = 0;
for ($i = 0; $i < $length; $i++) {
$divide = $divide * $frombase + $number[$i];
if ($divide >= $tobase) {
$number[$newlen++] = (int)($divide / $tobase);
$divide = $divide % $tobase;
} elseif ($newlen > 0) {
$number[$newlen++] = 0;
}
}
$length = $newlen;
$result = $tostring{$divide} . $result;
}
while ($newlen != 0);
return $result;
}

The easiest approach for any translation problems, from numeric base to human languages, is to translate via an intermediate format.
function bc_base_convert($num, $from, $to) {
return bc_convert_to(bc_parse_num($num, $from), $to);
}
Now all you need to write are bc_convert_to and bc_parse_num. If the platform distinguishes numeric types, you'll need to take this in to account. Also, floating point numbers require special consideration because a number may have a finite representation in one base, but not another (e.g. 1/3 is 0.13 but 0.333...10, and 1/1010 is .0001100110011...2).
As for a generalized explanation of how conversion works, consider how positional base systems work. A numeral of the form "anan-1...a1a0" in a base b represents the number "an*bn + an-1*bn-1 + ... + a1*b1 + a0*b0". Conversion basically works by evaluating the expression in the context of another base β.

Most of the examples I found on the internet and in this answers use BC Math functions. If you do not want to use use BC Math functions, you can have a look at this library:
http://www.lalit.org/lab/base62-php-convert-number-to-base-62-for-short-urls/
It doesn’t use BC Math functions so works without the use of BC Math
library.
It uses the native base_convert functions when the base is below 36 for faster execution.
The output number is backward compatible with the native base_convert function.
Can be used to convert to and from arbitrary bases between 2-64.

I wrote about using the BCMath functions for decimal/binary conversion here: http://www.exploringbinary.com/base-conversion-in-php-using-bcmath/ . You could easily modify that code to convert to different bases.
For example, in the case of converting integers, modify routines dec2bin_i() and bin2dec_i(). Rename them and add a base parameter -- something like dec2base_i($base,$decimal_i) and base2dec_i($base,$num_i), change the hardcoded '2' to the variable $base, convert the numeric remainders to/from characters of the base, and rename the variables.
Now, to convert between arbitrary bases, use decimal as an intermediate and call both those new functions. For example, convert base 42 number "123" to base 59 by calling $dec = base2dec_i('42','123') followed by $b59 = dec2base_i(59,$dec).
(You could also make a combined function that does it in one call.)

This function output the same than GNU Multiple Precision if possible…
<?php
function base_convert_alt($val,$from_base,$to_base){
static $gmp;
static $bc;
static $gmp62;
if ($from_base<37) $val=strtoupper($val);
if ($gmp===null) $gmp=function_exists('gmp_init');
if ($gmp62===null) $gmp62=version_compare(PHP_VERSION,'5.3.2')>=0;
if ($gmp && ($gmp62 or ($from_base<37 && $to_base<37)))
return gmp_strval(gmp_init($val,$from_base),$to_base);
if ($bc===null) $bc=function_exists('bcscale');
$range='0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
if ($from_base==10)
$base_10=$val;
else
{
$n=strlen(($val="$val"))-++$ratio;
if ($bc) for($i=$n;$i>-1;($ratio=bcmul($ratio,$from_base)) && $i--)
$base_10=bcadd($base_10,bcmul(strpos($range,$val[$i]),$ratio));
else for($i=$n;$i>-1;($ratio*=$from_base) && $i--)
$base_10+=strpos($range,$val[$i])*$ratio;
}
if ($bc)
do $result.=$range[bcmod($base_10,$to_base)];
while(($base_10=bcdiv($base_10,$to_base))>=1);
else
do $result.=$range[$base_10%$to_base];
while(($base_10/=$to_base)>=1);
return strrev($to_base<37?strtolower($result):$result);
}
echo base_convert_alt('2661500360',7,51);
// Output Hello

Related

php bit array in integer

I have written a wrapper class around a byte stream in order to read bit by bit from that stream (bit arrays) using this method:
public function readBits($len) {
if($len === 0) {
return 0;
}
if($this->nextbyte === null) {
//no byte has been started yet
if($len % 8 == 0) {
//don't start a byte with the cache, even number of bytes
$ret = 0;
//just return byte count not bit count
$len /= 8;
while ($len--) {
if($this->bytestream->eof()) {
//no more bytes
return false;
}
$byte = $this->bytestream->readByte();
$ret = ($ret << 8) | ord($byte);
}
return $ret;
} else {
$this->nextbyte = ord($this->bytestream->readByte());
$this->byteshift = 0;
}
}
if($len <= 8 && $this->byteshift + $len <= 8) {
//get the bitmask e.g. 00000111 for 3
$bitmask = self::$includeBitmask[$len - 1];
//can be satisfied with the remaining bits
$ret = $this->nextbyte & $bitmask;
//shift by len
$this->nextbyte >>= $len;
$this->byteshift += $len;
} else {
//read the remaining bits first
$bitsremaining = 8 - $this->byteshift;
$ret = $this->readBits($bitsremaining);
//decrease len by the amount bits remaining
$len -= $bitsremaining;
//set the internal byte cache to null
$this->nextbyte = null;
if($len > 8) {
//read entire bytes as far as possible
for ($i = intval($len / 8); $i > 0; $i--) {
if($this->bytestream->eof()) {
//no more bytes
return false;
}
$byte = $this->bytestream->readByte();
$ret = ($ret << 8) | ord($byte);
}
//reduce len to the rest of the requested number
$len = $len % 8;
}
//read a new byte to get the rest required
$newbyte = $this->readBits($len);
$ret = ($ret << $len) | $newbyte;
}
if($this->byteshift === 8) {
//delete the cached byte
$this->nextbyte = null;
}
return $ret;
}
This allows me to read bit arrays of arbitrary length off my byte stream which are returned in integers (as php has no signed integers).
The problem appears once I try to read a bit array that is bigger than 64 bits and I am assuming if I were to use the class on a 32 bit system the problem would appear with 32 bit arrays already.
The problem is that the return value is obviously to big to be held within an integer, so it topples over into a negative integer.
My question now is what would be the best way to deal with this. I can think of:
Forcing the number to be saved as a string (I am unsure if that's even possible)
Use the GMP extension (which I kinda don't want to because I think the gmp bitwise methods are probably quite a performance hit compared to the normal bitwise operators)
Is there something I missed on this or is one of the options I mentioned actually the best way to deal with this problem?
Thanks for your help in advance

Is there a faster way than x >= start && x <= end in PHP to test if an integer is between two integers?

This is a similar question to Fastest way to determine if an integer is between two integers (inclusive) with known sets of values, but the accepted answer will not work (as far as I know) in php due to php not being strictly typed and not having controllable integer overflow.
The use case here is to determine if an integer is between 65 and 90 (ASCII values for 'A' and 'Z'). These bounds might help optimize the solution due to 64 being a power of two and acting as boundary condition for this problem.
The only pseudo optimization I have come up with so far is:
//$intVal will be between 0 and 255 (inclusive)
function isCapital($intVal)
{
//255-64=191 (bit mask of 1011 1111)
return (($intVal & 191) <= 26) && (($intVal & 191) > 0);
}
This function is not much of an improvement (possibly slower) over a normal double comparison of $intVal >= 65 && $intVal <= 90, but it is just where I started heading while trying to optimize.
function isCapitalBitwise($intVal) {
return (($intVal & 191) <= 26) && (($intVal & 191) > 0);
}
function isCapitalNormal($intVal) {
return $intVal >= 65 && $intVal <= 90;
}
function doTest($repetitions) {
$i = 0;
$startFirst = microtime();
while ($i++ < $repetitions) {
isCapitalBitwise(76);
}
$first = microtime() - $startFirst;
$i = 0;
$startSecond = microtime();
while ($i++ < $repetitions) {
isCapitalNormal(76);
}
$second = microtime() - $startSecond;
$i = 0;
$startThird = microtime();
while ($i++ < $repetitions) {
ctype_upper('A');
}
$third = $startThird - microtime();
echo $first . ' ' . $second . ' ' . $third . PHP_EOL;
}
doTest(1000000);
On my system this returns:
0.217393 0.188426 0.856837
PHP is not as good at bitwise operations as compiled languages... but more importantly, I had to do a million comparisons to get less than 3 hundredths of a second of difference.
Even ctype_upper() is well in the range of "you might save a few seconds of CPU time per year" with these other ways of comparison, with the added bonus that you don't have to call ord() first.
Go for readability. Go for maintainability. Write your application, then profile it to see where your real bottlenecks are.
Instead of recreating the wheel, why not use the pre-built php method ctype_upper
$char = 'A';
echo ctype_upper($char) ? "It's uppercase" : "It's lowercase";
You can even pass in the integer value of a character:
echo ctype_upper($intVal) ? "It's uppercase" : "It's lowercase";
http://php.net/manual/en/function.ctype-upper.php
Even if you do find a method other than comparing via && or what I pasted above, it will be microseconds difference. You will waste hours coming up with a way to save a few seconds in the course of a year.
From How to check if an integer is within a range?:
t1_test1: ($val >= $min && $val <= $max): 0.3823 ms
t2_test2: (in_array($val, range($min, $max)): 9.3301 ms
t3_test3: (max(min($var, $max), $min) == $val): 0.7272 ms
You can also use range with characters (A, B, C...) but as you see it is not a good approach.
I think you will get best results by going native, but its only a fraction faster. Use ctype_upper directly. Here are my tests.
<?php
$numTrials = 500000;
$test = array();
for ($ii = 0; $ii < $numTrials; $ii++) {
$test[] = mt_rand(0, 255);
}
function compare2($intVal) {
return $intVal >= 65 && $intVal <= 90;
}
$tic = microtime(true);
for ($ii = 0; $ii < $numTrials; $ii++) {
$result = compare2($test[$ii]);
}
$toc = microtime(true);
echo "compare2...: " . ($toc - $tic) . "\n";
$tic = microtime(true);
for ($ii = 0; $ii < $numTrials; $ii++) {
$result = ctype_upper($test[$ii]);
}
$toc = microtime(true);
echo "ctype_upper: " . ($toc - $tic) . "\n";
echo "\n";
Which gives something pretty consistently like:
compare2...: 0.39210104942322
ctype_upper: 0.32374000549316

PHP "Maximum execution time"

I'm trying to program my own Sine function implementation for fun but I keep getting :
Fatal error: Maximum execution time of 30 seconds exceeded
I have a small HTML form where you can enter the "x" value of Sin(x) your looking for and the number of "iterations" you want to calculate (precision of your value), the rest is PhP.
The maths are based of the "Series definition" of Sine on Wikipedia :
--> http://en.wikipedia.org/wiki/Sine#Series_definition
Here's my code :
<?php
function factorial($int) {
if($int<2)return 1;
for($f=2;$int-1>1;$f*=$int--);
return $f;
};
if(isset($_POST["x"]) && isset($_POST["iterations"])) {
$x = $_POST["x"];
$iterations = $_POST["iterations"];
}
else {
$error = "You forgot to enter the 'x' or the number of iterations you want.";
global $error;
}
if(isset($x) && is_numeric($x) && isset($iterations) && is_numeric($iterations)) {
$x = floatval($x);
$iterations = floatval($iterations);
for($i = 0; $i <= ($iterations-1); $i++) {
if($i%2 == 0) {
$operator = 1;
global $operator;
}
else {
$operator = -1;
global $operator;
}
}
for($k = 1; $k <= (($iterations-(1/2))*2); $k+2) {
$k = $k;
global $k;
}
function sinus($x, $iterations) {
if($x == 0 OR ($x%180) == 0) {
return 0;
}
else {
while($iterations != 0) {
$result = $result+(((pow($x, $k))/(factorial($k)))*$operator);
$iterations = $iterations-1;
return $result;
}
}
}
$result = sinus($x, $iterations);
global $result;
}
else if(!isset($x) OR !isset($iterations)) {
$error = "You forgot to enter the 'x' or the number of iterations you want.";
global $error;
}
else if(isset($x) && !is_numeric($x)&& isset($iterations) && is_numeric($iterations)) {
$error = "Not a valid number.";
global $error;
}
?>
My mistake probably comes from an infinite loop at this line :
$result = $result+(((pow($x, $k))/(factorial($k)))*$operator);
but I don't know how to solve the problem.
What I'm tring to do at this line is to calculate :
((pow($x, $k)) / (factorial($k)) + (((pow($x, $k))/(factorial($k)) * ($operator)
iterating :
+ (((pow($x, $k))/(factorial($k)) * $operator)
an "$iterations" amount of times with "$i"'s and "$k"'s values changing accordingly.
I'm really stuck here ! A bit of help would be needed. Thank you in advance !
Btw : The factorial function is not mine. I found it in a PhP.net comment and apparently it's the optimal factorial function.
Why are you computing the 'operator' and power 'k' out side the sinus function.
sin expansion looks like = x - x^2/2! + x^3/3! ....
something like this.
Also remember iteration is integer so apply intval on it and not floatval.
Also study in net how to use global. Anyway you do not need global because your 'operator' and power 'k' computation will be within sinus function.
Best of luck.
That factorial function is hardly optimal—for speed, though it is not bad. At least it does not recurse. It is simple and correct though. The major aspect of the timeout is that you are calling it a lot. One technique for improving its performance is to remember, in a local array, the values for factorial previously computed. Or just compute them all once.
There are many bits of your code which could endure improvement:
This statement:
while($iterations != 0)
What if $iterations is entered as 0.1? Or negative. That would cause an infinite loop. You can make the program more resistant to bad input with
while ($iterations > 0)
The formula for computing a sine uses the odd numbers: 1, 3, 5, 7; not every integer
There are easier ways to compute the alternating sign.
Excess complication of arithmetic expressions.
return $result is within the loop, terminating it early.
Here is a tested, working program which has adjustments for all these issues:
<?php
// precompute the factorial values
global $factorials;
$factorials = array();
foreach (range (0, 170) as $j)
if ($j < 2)
$factorials [$j] = 1;
else $factorials [$j] = $factorials [$j-1] * $j;
function sinus($x, $iterations)
{
global $factorials;
$sign = 1;
for ($j = 1, $result = 0; $j < $iterations * 2; $j += 2)
{
$result += pow($x, $j) / $factorials[$j] * $sign;
$sign = - $sign;
}
return $result;
}
// test program to prove functionality
$pi = 3.14159265358979323846264338327950288419716939937510582097494459230781640628620;
$x_vals = array (0, $pi/4, $pi/2, $pi, $pi * 3/2, 2 * $pi);
foreach ($x_vals as $x)
{
$y = sinus ($x, 20);
echo "sinus($x) = $y\n";
}
?>
Output:
sinus(0) = 0
sinus(0.78539816339745) = 0.70710678118655
sinus(1.5707963267949) = 1
sinus(3.1415926535898) = 3.4586691443274E-16
sinus(4.7123889803847) = -1
sinus(6.2831853071796) = 8.9457384260403E-15
By the way, this executes very quickly: 32 milliseconds for this output.

PHP implementation for an URL shortening algorithm

I found Marcel Jackwerth's response to How to code a URL shortener? to be a good answer for the problem, however my question is how it'll look in PHP? Here's Marcel's answer:
You need a Bijective Function f (there must be no x1 != x2, that will make f(x1) = f(x2); and for every y you will find a x so that f(x)=y). This is necessary so that you can find a inverse function g('abc') = 123 for your f(123)='abc' function.
I would continue your "convert number to string" approach (however you will realize that your proposed algorithm fails if your id is a prime and greater than 52).
How to convert the id to a shortened url:
Think of an alphabet you want to use. In your case that's [a-zA-Z0-9]. It contains 62 letters.
Take the auto-generated unique numerical key (auto-incremented id): for example 125 (a decimal number)
Now you have to convert the 125 (base 10) to X (base 62). This will then be {2}{1} (2×62+1=125).
Now map the symbols {2} and {1} to your alphabet. Say {0} = 'a', {25} = 'z' and so on. We will have {2} = 'c' and {1} = 'b'. So '/cb' will be your shortened url.
How to resolve a shortened url abc to the initial id:
If you want to do this in reverse, it's not quite diffcult. 'e9a' will be resolved to "4th,61st,0th letter in alphabet" = {4}{61}{0}, which is 4×62×62 + 61×62 + 0 = 19158. You will then just have to find your database-record with id 19158.
function convert($src, $srcAlphabet, $dstAlphabet) {
$srcBase = strlen($srcAlphabet);
$dstBase = strlen($dstAlphabet);
$wet = $src;
$val = 0;
$mlt = 1;
while ($l = strlen($wet)) {
$digit = $wet[$l - 1];
$val += $mlt * strpos($srcAlphabet, $digit);
$wet = substr($wet, 0, $l - 1);
$mlt *= $srcBase;
}
$wet = $val;
$dst = '';
while ($wet >= $dstBase) {
$digitVal = $wet % $dstBase;
$digit = $dstAlphabet[$digitVal];
$dst = $digit . $dst;
$wet /= $dstBase;
}
$digit = $dstAlphabet[$wet];
$dst = $digit . $dst;
return $dst;
}
// prints cb
print convert('125', '0123456789', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789');
// prints 19158
print convert('e9a', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789', '0123456789');
I like this PHP function which allows you to customise the alphabet (and remove confusing 0/O's etc.)
// From http://snipplr.com/view/22246/base62-encode--decode/
private function base_encode($val, $base=62, $chars='0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ') {
$str = '';
do {
$i = fmod($val, $base);
$str = $chars[$i] . $str;
$val = ($val - $i) / $base;
} while($val > 0);
return $str;
}
Follow the URL to find the reverse 'decode' function too.
The main problem with Marcel's solution is that it uses a zero digit as a placeholder. By converting between bases, inevitably the numeral chosen to represent 0 can't appear at the front of the converted number.
For example, if you convert base 10 integers to base 4 using "ABCD" using the provided mechanism, there is no way to obtain output that starts with the letter "A", since that represents a zero in the new base and won't prefix the number. You might expect 5 to be "AA", but instead, it is "BA". There is no way to coerce that algorithm into producing "AA", because it would be like writing "00" in decimal, which has the same value as "0".
Here's an alternate solution in PHP that uses the entire gamut:
function encode($n, $alphabet = 'ABCD') {
$output = '';
if($n == 0) {
$output = $alphabet[0];
}
else {
$digits = floor(log($n, strlen($alphabet))) + 1;
for($z = 0; $z < $digits; $z++) {
$digit = $n % 4;
$output = $alphabet[$digit] . $output;
$n = floor($n / 4) - 1;
}
}
return $output;
}
function decode($code, $alphabet = 'ABCD') {
$n = 0;
$code = str_split($code);
$unit = 1;
while($letter = array_pop($code)) {
$n += (strpos($alphabet, $letter) + 1) * $unit;
$unit = $unit * strlen($alphabet);
}
return $n - 1;
}
echo encode(25); // should output "ABB"
echo decode('ABB'); // should output 25
Change/pass the second parameter to a list of characters to use instead of the short 4-character dictionary of "ABCD".
all you need to do is convert between different base systems base 10 to base 62
https://github.com/infinitas/infinitas/blob/dev/core/short_urls/models/short_url.php

Converting byte-stream into numeric data-type

Let's say I have a byte-stream in which I know the location of a 64-bit value (a 64-bit nonce). The byte-order is Little-Endian. As PHP's integer data-type is limited to 32-bit (at least on 32-bit operating systems) how would I convert the byte-sequence into a PHP numeric representation (float would be sufficient I think)?
$serverChallenge = substr($bytes, 24, 8);
// $serverChallenge now contains the byte-sequence
// of which I know that it's a 64-bit value
Just looked up the code for Zend_Crypt_Math_BigInteger_Bcmath and Zend_Crypt_Math_BigInteger_Gmp which deals with this problem:
Using BCmath (Big-Endian)
This is essentially the solution posted by Chad Birch.
public static function bc_binaryToInteger($operand)
{
$result = '0';
while (strlen($operand)) {
$ord = ord(substr($operand, 0, 1));
$result = bcadd(bcmul($result, 256), $ord);
$operand = substr($operand, 1);
}
return $result;
}
Using GMP (Big-Endian)
Same algorithem - just different function names.
public static function gmp_binaryToInteger($operand)
{
$result = '0';
while (strlen($operand)) {
$ord = ord(substr($operand, 0, 1));
$result = gmp_add(gmp_mul($result, 256), $ord);
$operand = substr($operand, 1);
}
return gmp_strval($result);
}
Changing the algorithem to use Litte-Endian byte-order is quite simple: just read the binary data from end to start:
Using BCmath (Litte-Endian)
public static function bc_binaryToInteger($operand)
{
// Just reverse the binray data
$operand = strrev($operand);
$result = '0';
while (strlen($operand)) {
$ord = ord(substr($operand, 0, 1));
$result = bcadd(bcmul($result, 256), $ord);
$operand = substr($operand, 1);
}
return $result;
}
Using GMP (Litte-Endian)
public static function gmp_binaryToInteger($operand)
{
// Just reverse the binray data
$operand = strrev($operand);
$result = '0';
while (strlen($operand)) {
$ord = ord(substr($operand, 0, 1));
$result = gmp_add(gmp_mul($result, 256), $ord);
$operand = substr($operand, 1);
}
return gmp_strval($result);
}
This seems like a total hack, but it should do the job, assuming you have the BC Math functions that daemonmoi recommended:
$result = "0";
for ($i = strlen($serverChallenge) - 1; $i >= 0; $i--)
{
$result = bcmul($result, 256); // shift result
$nextByte = (string)(ord($serverChallenge[$i]));
$result = bcadd($result, $nextByte);
}
Two years late to the party, but if anyone still cares:
unpack is the built-in way to go here, you can unpack it as a couple of 32-bit ints, or as a double.
I know this is not quite the answer to the question, but check out the BC Math functions to handle big numbers.

Categories