对于一个项目,我需要从MQTT读取信息。有效载荷充满了需要转换的protobuf信息。
对于某个值,我收到5.6904566139035E-28作为浮点数。使用http://www.exploringbinary.com/floating-point-converter/当我勾选单个和原始的十六进制值时,我可以转换它,然后我收到12345678,我应该拥有的值(我知道发送了什么)。
但现在我需要在PHP中进行转换。我不知道如何做到这一点。经过一番阅读后,我发现它是一个浮点,但如何转换就像在该网站上完成。
有人可以帮我解决这个问题!
非常感谢!
答案 0 :(得分:1)
使用非常神秘的 pack 和 unpack 函数,可以在一行中完成:
function rawSingleHex($num) {
return strrev(unpack('h*', pack('f', $num))[1]);
}
这个"打包" 将数字作为其二进制表示,然后"在包含一个元素的数组中解压缩" :十六进制格式的二进制表示。此格式的数字顺序相反,因此函数在最终结果中反转。
通过传递浮点数来调用它:
echo rawSingleHex(5.6904566139035E-28);
输出:
12345678
(这是我的原始答案,但是第一个选项可用,这不是建议的继续进行方式)
二进制格式在维基百科的Single-precision floating-point format文章中进行了解释。
这是一个实现上述过程的PHP函数:
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);
}
输出与第一个解决方案相同。