我正在开发一种设备的仿真器,该设备可以在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/

10-11 18:29