我正在开发一种设备的仿真器,该设备可以在quint16的2个内存空间中发送其 float 数据。到达服务器后,quint16数组的处理如下:
float Convert::toFloat(quint16 *value)
{
quint32 outValue;
quint32 q1 = (value[1])&0x0000ffff;
quint32 q2 = (value[0]<<16)&0xffff0000;
float v_value=0;
outValue = (q2)|q1;
memcpy(&v_value,&outValue,sizeof(float));
if (std::isnan(v_value)){
v_value = 0;
}
if (std::isinf(v_value)){
v_value = 0;
}
return v_value;
}
//In code
quint16 ReadResponseTable[MD_TCP_READ_TABLE_SIZE];
//fill ReadResponseTable
Convert::toFloat(&this->ReadResponseTable[MD_TCP_RELATIVE_ADDR_CH1+i*2])
现在,在开发仿真器时我需要做的与上述相反:我需要一个获取浮点数据并将其转换为quint16 *的函数,以便将其发送到服务器。问题是我不知道该怎么做。我对位操作感到恐惧。我搜索了SO和其他对象,但他们的答案充其量只是如何将float转换为单个quint16,而从未将两个内存空间分开。使用QDataStream或直接强制转换或memcpy的许多尝试也都失败了(通过将float转换为quint16并返回上面的函数进行测试,并且从未获得原始数字进行测试)。因此,任何帮助将不胜感激。
最佳答案
#include <QCoreApplication>
#include <QDataStream>
#include <QBuffer>
#include <QPair>
#include <QDebug>
static void setup_stream_helper(QDataStream &stream,
QDataStream::ByteOrder byteOrder,
QDataStream::FloatingPointPrecision floatingPrecision)
{
stream.setByteOrder(byteOrder);
stream.setFloatingPointPrecision(floatingPrecision);
}
// Forward conversion
float toFloat(quint16 a, quint16 b,
QDataStream::ByteOrder byteOrder,
QDataStream::FloatingPointPrecision floatingPrecision)
{
QDataStream stream;
QBuffer buffer;
buffer.open(QIODevice::ReadWrite);
stream.setDevice(&buffer);
setup_stream_helper(stream, byteOrder, floatingPrecision);
stream << a << b;
qDebug() << buffer.buffer().toHex(' '); // control what bytes your really has
buffer.seek(0);
float ret = 0;
stream >> ret;
return ret;
}
// Backwards conversion
QPair<quint16, quint16> fromFloat(float val,
QDataStream::ByteOrder byteOrder,
QDataStream::FloatingPointPrecision floatingPrecision)
{
QDataStream stream;
QBuffer buffer;
buffer.open(QIODevice::ReadWrite);
stream.setDevice(&buffer);
setup_stream_helper(stream, byteOrder, floatingPrecision);
stream << val;
qDebug() << buffer.buffer().toHex(' '); // control what bytes your really has
buffer.seek(0);
QPair<quint16, quint16> ret;
stream >> ret.first >> ret.second;
return ret;
}
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
auto byteOrders = { QDataStream::LittleEndian, QDataStream::BigEndian };
auto floatingPrecision = QDataStream::SinglePrecision;
qDebug() << "float -> quint16 ->float test:";
float floats[] = { 0, -100.0, 123.123, -456.789, FLT_MAX, FLT_MIN, -FLT_MAX };
for(QDataStream::ByteOrder byteOrder : byteOrders)
{
for(float val : floats)
{
qDebug() << "source float val =" << val;
QPair<quint16, quint16> pair = fromFloat(val, byteOrder, floatingPrecision);
qDebug() << "converted to quint16 pair =" << pair;
float newVal = toFloat(pair.first, pair.second, byteOrder, floatingPrecision);
qDebug() << "converted backwards to float val =" << newVal;
Q_ASSERT(qFuzzyCompare(newVal, val));
qDebug() << "\n------------------";
}
}
qDebug() << "\nbackwards, quint16 ->float -> quint16 test:";
quint16 as[] = { 0, 10, 100, 1000, 99, 999, UINT16_MAX};
quint16 bs[] = { 5, 15, 55, 125, 555, 777, 0};
for (QDataStream::ByteOrder byteOrder : byteOrders)
{
for (quint16 a : as)
{
for (quint16 b : bs)
{
QPair<quint16, quint16> pair(a, b);
qDebug() << "sourse quint16 pair =" << pair;
float val = toFloat(pair.first, pair.second, byteOrder, floatingPrecision);
qDebug() << "converted to float val =" << val;
QPair<quint16, quint16> newPair = fromFloat(val, byteOrder, floatingPrecision);
qDebug() << "pair quint16 conveted backwards =" << newPair;
Q_ASSERT(newPair == pair);
qDebug() << "\n------------------";
}
}
}
return a.exec();
}
关于c++ - 如何将浮点值转换为quint16数组?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/59379505/