public function packU64($v)
{
if (!is_numeric($v)) {
throw new \InvalidArgumentException('Input must be numeric.');
}
// x64
if (PHP_INT_SIZE >= 8) {
if ($v < 0) {
throw new \InvalidArgumentException('Input must be positive.');
}
// x64, int
if (is_int($v)) {
return pack('NN', $v >> 32, $v & 0xffffffff);
}
// x64, bcmath
if (function_exists('bcmul')) {
$h = bcdiv($v, 4294967296, 0);
$l = bcmod($v, 4294967296);
return pack('NN', $h, $l);
}
// x64, no-bcmath
$p = max(0, strlen($v) - 13);
$lo = (int) substr($v, $p);
$hi = (int) substr($v, 0, $p);
$m = $lo + $hi * 1316134912;
$l = $m % 4294967296;
$h = $hi * 2328 + (int) ($m / 4294967296);
return pack('NN', $h, $l);
}
// x32, int
if (is_int($v)) {
return pack('NN', 0, $v);
}
// x32, bcmath
if (function_exists('bcmul')) {
$h = bcdiv($v, '4294967296', 0);
$l = bcmod($v, '4294967296');
// conversion to float is intentional; int would lose 31st bit
return pack('NN', (double) $h, (double) $l);
}
// x32, no-bcmath
$p = max(0, strlen($v) - 13);
$lo = (double) substr($v, $p);
$hi = (double) substr($v, 0, $p);
$m = $lo + $hi * 1316134912.0;
$q = floor($m / 4294967296.0);
$l = $m - $q * 4294967296.0;
$h = $hi * 2328.0 + $q;
return pack('NN', $h, $l);
}