Qt之小端模式数据转大端模式数据

在项目过程中,遇到一个小端模式的数据解析问题,之前没有转化的经验,折腾了好久才转化成功,记录下来

首先,解释下什么是小端模式和大端模式

  • 大端模式(Big Endian):数据的高字节,保存在内存的低地址中;数据的低字节,保存在内存的高地址中。
  • 小端模式(Little Endian):数据的高字节,保存在内存的高地址中;数据的低字节,保存在内存的低地址中。

举一个例子,比如数字0x12 34 56 78在内存中的表示形式为:
1)大端模式:
低地址 -----------------> 高地址
0x12  |  0x34  |  0x56  |  0x78
2)小端模式:
低地址 ------------------> 高地址
0x78  |  0x56  |  0x34  |  0x12
可见,大端模式和字符串的存储模式类似。

然后就是具体的转化过程了,项目背景是解析某惯导产品的数据,第46/47/48个字节表示东向速度,但是是用小端模式保存的(MSB LSB:起始地址为最高位, 最后地址为最低位。LSB MSB:起始地址为最低位,最后地址为最高位。)

接收完原始数据后,为了显示和保存方便,将数据存储为16进制字符串的形式,如原始数据是三个字节0x01 0x02 0x03,保存为QString类型“010203”,然后采用如下的方法进行数据的解析

//小端数据转为大端数据,并解析
//输入的数据是3个16进制字符串,如“FF002A”,进行移位操作时需要先分开
int MainWindow::changeEndian(QString qstr)
{

    //用int移位的方法
    bool ok;
    QString str1 = qstr.mid(0,2);
    QString str2 = qstr.mid(2,2);
    QString str3 = qstr.mid(4,2);
    uint data1 = str1.toInt(&ok,16);
    uint data2 = str2.toInt(&ok,16);
    uint data3 = str3.toInt(&ok,16);
    int num = (data3 << 16) + (data2 << 8) + data1;

    //用char* 移位的方法,注意此时输入的不能是16进制字符串,而应该转化为对应的字符,才可以移位操作
//    string str = qstr.toStdString();
//    //qDebug() << "QString " << qstr << endl;
//    cout << "str " << str << endl;
//    const char* data = str.data();
//    cout << "char " << data << endl;
//    uint8_t data2 = uint8_t(*(data+4));
//    uint8_t data1 = uint8_t(*(data+1));
//    uint8_t data0 = uint8_t(*(data));
//    cout << "data+2 " << data2 << " data+1 " << data1 << " data0 " << data0 << endl;
//    uint8_t num = (uint8_t(*(data + 2) << 16) + uint8_t(*(data+1) << 8) + uint8_t(*data));
    //FFFFFF对应的最大值是16777216,一半值来区分正负,注意负数采用补码方法
    if(num >= 8388608)
        num = num - 16777216;
    //cout << "num " << num << endl;
    return num;
}

 

 

相关推荐
©️2020 CSDN 皮肤主题: 游动-白 设计师:白松林 返回首页