public function unpackI64($v)
{
list($hi, $lo) = array_values(unpack('N*N*', $v));
// x64
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;
}
return ($hi << 32) + $lo;
}
// x32, int
if ($hi == 0) {
if ($lo > 0) {
return $lo;
}
return sprintf('%u', $lo);
} elseif ($hi == -1) {
// x32, int
if ($lo < 0) {
return $lo;
}
return sprintf('%.0f', $lo - 4294967296.0);
}
$neg = '';
$c = 0;
if ($hi < 0) {
$hi = ~$hi;
$lo = ~$lo;
$c = 1;
$neg = '-';
}
$hi = sprintf('%u', $hi);
$lo = sprintf('%u', $lo);
// x32, bcmath
if (function_exists('bcmul')) {
return $neg . bcadd(bcadd($lo, bcmul($hi, '4294967296')), $c);
}
// 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 + $c;
$h = $q * 4294967296.0 + $r * 429.0 + $mq;
if ($l == 10000000) {
$l = 0;
$h++;
}
$h = sprintf('%.0f', $h);
$l = sprintf('%07.0f', $l);
if ($h == '0') {
return $neg . sprintf('%.0f', (double) $l);
}
return $neg . $h . $l;
}