I'm trying to convert a 64-bit float to a 64-bit integer (and back) in php. I need to preserve the bytes, so I'm using the pack and unpack functions. The functionality I'm looking for is basically Java's Double.doubleToLongBits() method. http://docs.oracle.com/javase/7/docs/api/java/lang/Double.html#doubleToLongBits(double)
I managed to get this far with some help from the comments on the php docs for pack():
function encode($int) {
$int = round($int);
$left = 0xffffffff00000000;
$right = 0x00000000ffffffff;
$l = ($int & $left) >>32;
$r = $int & $right;
return unpack('d', pack('NN', $l, $r))[1];
}
function decode($float) {
$set = unpack('N2', pack('d', $float));
return $set[1] << 32 | $set[2];
}
And this works well, for the most part...
echo decode(encode(10000000000000));
100000000
echo encode(10000000000000);
1.1710299640683E-305
But here's where it gets tricky...
echo decode(1.1710299640683E-305);
-6629571225977708544
I have no idea what's wrong here. Try it for yourself: http://pastebin.com/zWKC97Z7
You'll need 64-bit PHP on linux. This site seems to emulate that setup: http://www.compileonline.com/execute_php_online.php
echo encode(10000000000000) - 1.1710299640683E-305; // 2.3525429792377E-319
So the question is, do you want the string to be 100% accurate? – Talbotprintf
and php.ini'sprecision=
... However, I've decided to stay away from type conversions while using php from now on. – Matte