在PHP中将IEEE754转换为十六进制

对于项目,我需要从MQTT读取信息。 有效载荷填充了需要转换的protobuf信息。</ p>

对于某个值,我收到5.6904566139035E-28作为浮点数。 使用 http://www.exploringbinary.com/floating-point-converter/ I 当我勾选单个和原始的十六进制值时可以转换这个,然后我收到12345678,我应该拥有的值(我知道发送了什么)。</ p>

但是现在我需要在 PHP。 我不知道如何做到这一点。 经过一番阅读后,我发现它是一个浮点,但如何转换就像在该网站上完成。 </ p>

是否有人可以帮我解决这个问题! </ p>

非常感谢!</ p>
</ div>

展开原文

原文

For a project I need to read in information from MQTT. The payload is filled with protobuf information, that needs to be converted.

For a certain value I receive 5.6904566139035E-28 as float. Using http://www.exploringbinary.com/floating-point-converter/ I can convert this when I tick single and raw hexadecimal value, then I receive 12345678, the value I should have (I know what is sent).

But now I need to do that conversion in PHP. I haven't any idea how this could be done. After some reading I figured out it is a Floating Point, but how to convert this like done on that website.

Is there someone that can help me with this!

Thanks a lot!

dounong5373
dounong5373 听起来你需要一个更好的protobuf解析器,然后!:p无论如何,你应该可以通过使用pack和unpack来获得
4 年多之前 回复
douzhong4222
douzhong4222 谢谢,我使用了一种protobuf解析器,但这给了我这个'答案'
4 年多之前 回复
doujingya1166
doujingya1166 不要自己阅读protobuf,使用现成的库(例如pecl.php.net/package/protocolbuffers)
4 年多之前 回复

1个回答



使用非常神秘的 pack </ em>和 unpack </ em>函数,可以在 单行:</ p>

  function rawSingleHex($ num){
return strrev(unpack('h *',pack('f',$ num))[1 ]);
}
</ code> </ pre>

“打包”</ em>数字作为其二进制表示,然后“解包”</ em>它在一个包含一个元素的数组中:十六进制格式的二进制表示。 此格式的数字顺序相反,因此函数在最终结果中反转。</ p>

通过传递浮点数来调用它:</ p>

  echo rawSingleHex(5.6904566139035E-28); 
</ code> </ pre>

输出:</ p>


12345678 < / p>
</ blockquote>

没有 pack </ em> / pack </ em> </ h3>

(这是我的原创 回答,但第一个选项可用,这不是建议的继续方式)</ p>

二进制格式在维基百科关于单精度浮点格式。</ p>

这是一个实现了 描述过程:</ p>

  function rawSingleHex($ num){
if if($ num == 0)返回'00000000';
//设置符号位,然后添加另一个 ,较高的一个,稍后将被剥离
$ sign = $ num&lt; 0? 0x300:0x200;
$ significant = abs($ num);
$ exponent = floor(log($ significant,2));
//在逗号前得到24个最重要的二进制位:
$ significant = round($ significant / pow(2,$ exponent-23));
//指数具有指数偏差格式:
$ exponent + = 127;
//格式:1符号位+ 8指数位+ 23 有效位,
//没有最左边的“1”有效
$ bin = substr(decbin($ sign + $ exponent),1)。

substr(decbin($ significant),1);
//断言结果具有正确的位数:
if(strlen($ bin)!== 32){
返回“意外错误”; \ n}
//将二进制表示转换为十六进制,正好是8位

返回str_pad(dechex(bindec($ bin)),8,“0”,STR_PAD_LEFT);
}
</ code> </ pre>

输出与第一个解决方案相同的内容。</ p>
</ div>

展开原文

原文

With the quite cryptic pack and unpack functions, it can be done in a one-liner:

function rawSingleHex($num) {
    return strrev(unpack('h*', pack('f', $num))[1]);
}

This "packs" the number as its binary representation, then "unpacks" it in an array with one element: the binary representation in hexadecimal format. This format has the digits in the reversed order, so the function reverses that in the final result.

Call it by passing the floating point number:

echo rawSingleHex(5.6904566139035E-28);

Output:

12345678

Without pack/pack

(this was my original answer, but with the first option being available, this is not the advised way to proceed)

The binary format is explained in Wikipedia's 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 solution.

doukang7858
doukang7858 请查看更新的答案。 打包/打包比使用我最初提供的功能更好。 它将具有更好的性能并且非常紧凑。
4 年多之前 回复
Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问