2 个字节到自定义格式浮点数

2 bytes to custom format floating point

我有一个符合以下规范的字节数组:

byte[0]: upper 4 bits is the exponential part, the rest is significant (high)
byte[1]: significant low
Number of decimals is 2
Unit is in "m"

full specification(P2 设备控制 > P2_Device_Control_Protocol_&_Command.pdf > 第 111 页)

一些示例值:

 0xB3 0x70 should be 8,8mm (but units is in m so 0,0088m or 0m (only 2 decimals)
 0xC3 0xE9 should be 100mm (so 0,10m)
 0xC6 0xE0 should be 176mm (so 0,176m)

如何在 C++ 中将此自定义浮点数据转换为普通浮点数

感谢您的帮助!

规格为

(得到参考值后,指数好像不是2的次方,而是10的(负)次方)

那么对应的整数值为

value = (byte[1] + (byte[0] & 15) * 256);
exponent = (byte[0] >> 4) - 16;
float_val = (float)value * pow(10.f, (float)exponent);

并且可以通过转换将其转换为浮点数,其中字节必须是指向 unsigned char.

的指针

根据提供的值和给定的指数 k 和尾数 s,该值的公式似乎是

s * 10^(k-16)

^ 在这里求幂)

这样您就可以将转换实现为

#include <iostream>
#include <cmath>

constexpr float toExponent(unsigned char value)
{
    return value - 16;
}

float convert(unsigned char bytes[2])
{
    auto significand = ((static_cast<unsigned int>(bytes[0]) & 0b1111) << 8) | bytes[1];

    auto exponent = toExponent(bytes[0] >> 4);

    return std::powf(10, exponent) * significand;
}

//demonstrate conversions of provided values
int main()
{
    unsigned char val[2]{ 0xB3, 0x70};
    unsigned char val2[2]{ 0xC3, 0xE9 };
    unsigned char vals[][2]
    {
        {0xB3, 0x70}, // 0.0088
        {0xC3, 0xE9}, // 0.1
        {0xC6, 0xE0}, // 0.176
    };

    for (size_t i = 0; i != 3; ++i)
    {
        std::cout << convert(vals[i]) << '\n';
    }
    

    return 0;
}

请注意,正如@chtz 在评论中提到的,指数也可以是使用 2s 补码表示的 4 位整数,如果指数的第一位为 0,这可能会导致不同的值。这将是更可取的,如果你能得到这个案例的价值转换。