在IEEE中将IEEE754转换为十六进制 [英] Convert IEEE754 to hex in PHP

查看:572
本文介绍了在IEEE中将IEEE754转换为十六进制的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对于一个项目,我需要从MQTT中读取信息。有效负载填充protobuf信息,需要进行转换。

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

但现在我需要在PHP中进行转换。我不知道如何做到这一点。经过一番阅读,我发现这是一个浮点,但如何转换,就像在网站上做的一样。

有没有人可以帮助我呢!



非常感谢!

解决方案

> pack 和 unpack 函数,可以在一行中完成:

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

$ / code>

这个打包表示,然后将其解压缩到一个数组中,其中包含一个元素:十六进制格式的二进制表示。这个格式的数字是相反的顺序,所以函数在最终结果中反转。

通过传递浮点数来调用它:

  echo rawSingleHex(5.6904566139035E-28); 

输出:


12345678



没有 pack / pack



(这是我原来的答案,但第一个选项可用,这不是建议的方式进行)

二进制格式在维基百科有关单精度浮点格式的文章中进行了解释。



下面是一个PHP函数,它实现了描述的过程:

pre $ 函数rawSingleHex($ num){
if($ num == 0)return'00000000';
//设置符号位,并添加另一个较高的,稍后将被剥离的
$ sign = $ num< 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 + $指数),1)。
substr(decbin($ significant),1);
//断言结果有正确的位数:
if(strlen($ bin)!== 32){
returnunexpected error;

//将二进制表示转换为十六进制,正好有8位
return str_pad(dechex(bindec($ bin)),8,0,STR_PAD_LEFT);
}

输出与第一个解决方案相同。 $ b

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!

解决方案

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.

这篇关于在IEEE中将IEEE754转换为十六进制的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆