qt-通信协议基础-double转成QbyteArray-小端系统

提问

8个字节 (64 bits) 双精度浮点数 (依据IEEE 754标准) ,Qt C++double怎么转成QbyteArray?

核心实现代码(C++/Qt)

cpp 复制代码
#include <QByteArray>
#include <QDebug>
#include <cstring>
// 基础版本:直接内存复制(系统字节序)
QByteArray doubleToQByteArray(double value) {
    QByteArray bytes;
    bytes.resize(sizeof(double));
    memcpy(bytes.data(), &value, sizeof(value));
    return bytes;
}
// 增强版本:可选字节序转换
QByteArray doubleToQByteArray(double value, bool bigEndian) {
    union {
        double d;
        quint64 i;
    } converter;
    converter.d = value;
    QByteArray bytes;
    bytes.resize(8);
    if (bigEndian) {
        // 大端序:高位在前
        bytes[0] = (converter.i >> 56) & 0xFF;
        bytes[1] = (converter.i >> 48) & 0xFF;
        bytes[2] = (converter.i >> 40) & 0xFF;
        bytes[3] = (converter.i >> 32) & 0xFF;
        bytes[4] = (converter.i >> 24) & 0xFF;
        bytes[5] = (converter.i >> 16) & 0xFF;
        bytes[6] = (converter.i >> 8)  & 0xFF;
        bytes[7] = converter.i        & 0xFF;
    } else {
        // 小端序:低位在前
        bytes[7] = (converter.i >> 56) & 0xFF;
        bytes[6] = (converter.i >> 48) & 0xFF;
        bytes[5] = (converter.i >> 40) & 0xFF;
        bytes[4] = (converter.i >> 32) & 0xFF;
        bytes[3] = (converter.i >> 24) & 0xFF;
        bytes[2] = (converter.i >> 16) & 0xFF;
        bytes[1] = (converter.i >> 8)  & 0xFF;
        bytes[0] = converter.i        & 0xFF;
    }
    return bytes;
}
// 反向转换验证
double qByteArrayToDouble(const QByteArray& bytes, bool bigEndian) {
    quint64 temp;
    if (bigEndian) {
        temp  = (static_cast<quint64>(bytes[0] & 0xFF) << 56);
        temp |= (static_cast<quint64>(bytes[1] & 0xFF) << 48);
        temp |= (static_cast<quint64>(bytes[2] & 0xFF) << 40);
        temp |= (static_cast<quint64>(bytes[3] & 0xFF) << 32);
        temp |= (static_cast<quint64>(bytes[4] & 0xFF) << 24);
        temp |= (static_cast<quint64>(bytes[5] & 0xFF) << 16);
        temp |= (static_cast<quint64>(bytes[6] & 0xFF) << 8);
        temp |= (static_cast<quint64>(bytes[7] & 0xFF));
    } else {
        temp  = (static_cast<quint64>(bytes[7] & 0xFF) << 56);
        temp |= (static_cast<quint64>(bytes[6] & 0xFF) << 48);
        temp |= (static_cast<quint64>(bytes[5] & 0xFF) << 40);
        temp |= (static_cast<quint64>(bytes[4] & 0xFF) << 32);
        temp |= (static_cast<quint64>(bytes[3] & 0xFF) << 24);
        temp |= (static_cast<quint64>(bytes[2] & 0xFF) << 16);
        temp |= (static_cast<quint64>(bytes[1] & 0xFF) << 8);
        temp |= (static_cast<quint64>(bytes[0] & 0xFF));
    }
    double result;
    memcpy(&result, &temp, sizeof(result));
    return result;
}
// 测试用例
int main() {
    double pi = 3.141592653589793;
    
    // 测试系统字节序(自动适应当前平台)
    QByteArray nativeBytes = doubleToQByteArray(pi);
    qDebug() << \"Native bytes (hex):\" << nativeBytes.toHex(' ');
    
    // 测试大端序(网络标准)
    QByteArray bigEndianBytes = doubleToQByteArray(pi, true);
    qDebug() << \"Big-endian bytes (hex):\" << bigEndianBytes.toHex(' ');
    
    // 反向验证
    double reversed = qByteArrayToDouble(bigEndianBytes, true);
    qDebug() << \"Reversed value:\" << reversed;
    
    return 0;
}

关键技术要点

  • 内存布局标准
    严格遵循IEEE 754双精度浮点数标准:
    • 1位符号位
    • 11位指数(偏移量1023)
    • 52位尾数(隐含前导1)
    • 示例值π的十六进制表示:
    • 大端序:40 09 21 FB 54 44 2D 18
    • 小端序:18 2D 44 54 FB 21 09 40
  • 字节序处理
    • 系统默认字节序:使用memcpy直接复制内存,保持与当前系统一致
    • 强制大端序:通过位移操作手动构造字节序,适用于网络传输和硬件通信
    • 自动检测字节序:可通过QSysInfo::ByteOrder获取当前系统字节序
  • 类型安全设计
    • 使用union进行类型双射,避免指针类型转换带来的未定义行为
    • 显式处理字节序参数,增强代码可读性和可维护性
  • 跨平台兼容性
    • 代码不依赖特定平台的字节序特性
    • 通过参数化设计支持不同场景需求
    • 兼容Windows/Linux/macOS等主流Qt平台

性能优化建议

  • 批量处理:对大量浮点数转换时,预分配QByteArray内存块,减少重复分配开销
  • 缓存机制:频繁转换相同值时可考虑结果缓存
  • SIMD优化:在支持SIMD的平台上,可使用Intel SSE或ARM NEON指令进行并行转换

典型应用场景

  • 传感器数据采集系统
  • 工业控制协议实现
  • 科学计算数据序列化
  • 音频/视频处理中的浮点数据存储
  • 硬件设备通信接口实现

其它资料

qt-通信协议基础-QStirng转QByteArray-进阶操作

相关推荐
没钥匙的锁12 小时前
16-Java反射机制:Spring IOC背后的核心技术
java·开发语言·spring
起予者汝也2 小时前
Python 数据结构
开发语言·数据结构·python
ECT-OS-JiuHuaShan4 小时前
严格证明:还原论是ASCII,整体论是UTF-8的历史意义和价值
开发语言·人工智能·算法·量子计算
AC赳赳老秦4 小时前
时间开销自动统计:OpenClaw 记录工作任务时长、分析时间分配、给出优化建议
java·大数据·开发语言·python·自动化·deepseek·openclaw
祉猷并茂,雯华若锦4 小时前
Appium 3.x 实战:元素定位与常见错误解析
开发语言·python·appium
Lethehong5 小时前
飞算Java:从需求梳理到风险闭环,搭建云盾企业信息安全与权限管理平台
java·开发语言
爱喝水的鱼丶5 小时前
SAP-ABAP:ALV数据导出增强——实现Excel/PDF/CSV多格式自定义导出
开发语言·性能优化·sap·abap·erp
Mortalbreeze5 小时前
深入理解 Linux 线程机制(四):线程同步——条件变量与信号量
linux·运维·服务器·开发语言·c++
不会c+5 小时前
C语言:入门到精通(408考研版)系列七 派生的数据类型
c语言·开发语言
不定积分要+C_yyy6 小时前
Java基础核心精讲:基本数据类型与包装类区别、自动装箱拆箱与缓存陷阱实战解析
java·开发语言