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,这可能会导致不同的值。这将是更可取的,如果你能得到这个案例的价值转换。
我有一个符合以下规范的字节数组:
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,这可能会导致不同的值。这将是更可取的,如果你能得到这个案例的价值转换。