Modbus协议中浮点数(单精度)使用的是IEEE754标准浮点数(32位)的表示方法:

Modbus.Float_.Format.png

IEEE754浮点数二进制格式示意图

1[31] 符号位(SIGN)

8[23-30] 指数位(EXPONENT) 指数偏移量 127

23[0-22] 尾数位(MANTISSA)

转换为10进制的公式:

SGL = (-1)^SIGN * 1.MANTISSA * 2^(EXPONENT-127)

转换举例:

将40800000转换为10进制数,方法如下:

Modbus.Float_.Format.Example.png

Modbus浮点数转换示例

先将16进制数转成二进制数01000000100000000000000000000000

1位符号位(SIGN)=0

8位指数位(EXPONENT)=10000001=129[10进制]

23位尾数位(MANTISSA)=00000000000000000000000

1.尾数=1 .00000000000000000000000=1.0000000[10进制]

套入公式得SGL=(-1)^0*1.0000000*2^(129-127)=4

PHP算法代码:

    /**
     * 十六进制字符串转换为32位IEEE754浮点数
     *
     * @param  string $hex 十六进制字符串
     * @return float
     */
    public static function hex32float($hex)
    {
        $v = hexdec($hex);
        $x = ($v & ((1 << 23) - 1)) + (1 << 23) * ($v >> 31 | 1);
        $exp = ($v >> 23 & 0xFF) - 127;
        return $x * pow(2, $exp - 23);
    }

本文转自:http://www.goupteam.com/tech-expand/1216.html