public function unpackU64($v)
{
list($hi, $lo) = array_values(unpack('N*N*', $v));
if (PHP_INT_SIZE >= 8) {
if ($hi < 0) {
// because php 5.2.2 to 5.2.5 is totally fucked up again
$hi += 1 << 32;
}
if ($lo < 0) {
$lo += 1 << 32;
}
// x64, int
if ($hi <= 2147483647) {
return ($hi << 32) + $lo;
}
// x64, bcmath
if (function_exists('bcmul')) {
return bcadd($lo, bcmul($hi, '4294967296'));
}
// x64, no-bcmath
$c = 100000;
$h = ((int) ($hi / $c) << 32) + (int) ($lo / $c);
$l = ($hi % $c << 32) + $lo % $c;
if ($l > $c) {
$h += (int) ($l / $c);
$l = $l % $c;
}
if ($h == 0) {
return $l;
}
return sprintf('%d%05d', $h, $l);
}
// x32, int
if ($hi == 0) {
if ($lo > 0) {
return $lo;
}
return sprintf('%u', $lo);
}
$hi = sprintf('%u', $hi);
$lo = sprintf('%u', $lo);
// x32, bcmath
if (function_exists('bcmul')) {
return bcadd($lo, bcmul($hi, '4294967296'));
}
// x32, no-bcmath
$hi = (double) $hi;
$lo = (double) $lo;
$q = floor($hi / 10000000.0);
$r = $hi - $q * 10000000.0;
$m = $lo + $r * 4967296.0;
$mq = floor($m / 10000000.0);
$l = $m - $mq * 10000000.0;
$h = $q * 4294967296.0 + $r * 429.0 + $mq;
$h = sprintf('%.0f', $h);
$l = sprintf('%07.0f', $l);
if ($h == '0') {
return sprintf('%.0f', (double) $l);
}
return $h . $l;
}