With pretty cryptic packages and unpacking features, this can be done in single-line mode:
function rawSingleHex($num) { return strrev(unpack('h*', pack('f', $num))[1]); }
This “packs” the number as its binary representation, then “unpacks” it into an array with one element: the binary representation in hexadecimal format. This format has the numbers in reverse order, so the function cancels this in the final result.
Call it by passing a floating point number:
echo rawSingleHex(5.6904566139035E-28);
Output:
12345678
No package / package
(this was my initial answer, but with the first option available, this is not a recommended way to continue)
The binary format is explained in the Wikipedia article on the single-precision floating point format .
Here is a PHP function that implements the described procedure:
function rawSingleHex($num) { if ($num == 0) return '00000000'; // set sign bit, and add another, higher one, which will be stripped later $sign = $num < 0 ? 0x300 : 0x200; $significant = abs($num); $exponent = floor(log($significant, 2)); // get 24 most significant binary bits before the comma: $significant = round($significant / pow(2, $exponent-23)); // exponent has exponent-bias format: $exponent += 127; // format: 1 sign bit + 8 exponent bits + 23 significant bits, // without left-most "1" of significant $bin = substr(decbin($sign + $exponent), 1) . substr(decbin($significant), 1); // assert that result has correct number of bits: if (strlen($bin) !== 32) { return "unexpected error"; } // convert binary representation to hex, with exactly 8 digits return str_pad(dechex(bindec($bin)), 8, "0", STR_PAD_LEFT); }
It outputs the same as in the first decision.
trincot
source share