关于SimpleMsgPack中swap引发的问题大端法和小端法研究笔记

简介: 今天diocp裙中[珠海]-芒果反应了一个关于SimpleMsgPack的问题 msgPack.AsFloat = 2.507182; 经过编码再解码后,会直接触发异常。 因为msgPack的标准,在打包的数据是大端法IEEE 754 下面是msgPack的标准说明   Float ...

今天diocp裙中[珠海]-芒果反应了一个关于SimpleMsgPack的问题

msgPack.AsFloat = 2.507182;

经过编码再解码后,会直接触发异常。

因为msgPack的标准,在打包的数据是大端法IEEE 754

下面是msgPack的标准说明

 
Float format family stores a floating point number in 5 bytes or 9 bytes.
float 32 stores a floating point number in IEEE 754 single precision floating point number format:
+--------+--------+--------+--------+--------+
|  0xca  |XXXXXXXX|XXXXXXXX|XXXXXXXX|XXXXXXXX
+--------+--------+--------+--------+--------+

float 64 stores a floating point number in IEEE 754 double precision floating point number format:
+--------+--------+--------+--------+--------+--------+--------+--------+--------+
|  0xcb  |YYYYYYYY|YYYYYYYY|YYYYYYYY|YYYYYYYY|YYYYYYYY|YYYYYYYY|YYYYYYYY|YYYYYYYY|
+--------+--------+--------+--------+--------+--------+--------+--------+--------+
where
* XXXXXXXX_XXXXXXXX_XXXXXXXX_XXXXXXXX is a big-endian IEEE 754 single precision floating point number
* YYYYYYYY_YYYYYYYY_YYYYYYYY_YYYYYYYY_YYYYYYYY_YYYYYYYY_YYYYYYYY_YYYYYYYY is a big-endian
  IEEE 754 double precision floating point number

 

小端法变大端法把自己顺序调整下就好了

在SimpleMsgPack中有一个这样的函数,可以对Double类型的数据进行交换字节数。

procedure swap64Ex(const v; out outVal);
begin
  // 7F F5 B8 6F B5 0E 04 40

  // 40 04 0E B5 6F B8 F5 7F
  PByte(@outVal)^ := PByte(IntPtr(@v) + 7)^;
  PByte(IntPtr(@outVal) + 1)^ := PByte(IntPtr(@v) + 6)^;
  PByte(IntPtr(@outVal) + 2)^ := PByte(IntPtr(@v) + 5)^;
  PByte(IntPtr(@outVal) + 3)^ := PByte(IntPtr(@v) + 4)^;
  PByte(IntPtr(@outVal) + 4)^ := PByte(IntPtr(@v) + 3)^;
  PByte(IntPtr(@outVal) + 5)^ := PByte(IntPtr(@v) + 2)^;
  PByte(IntPtr(@outVal) + 6)^ := PByte(IntPtr(@v) + 1)^;
  PByte(IntPtr(@outVal) + 7)^ := PByte(@v)^;
end;

然后我重载了一些函数 这个函数对传入的Double进行交换字节然后返回Double类型

function swap(v:Double): Double; overload;
begin
  swap64Ex(v, Result);
end;

 

上面这个浮点数据 2.507182,经过交换后 如果仍然用Double类型来存放会是一个NaN, 会触发一个无效的浮点型数据的异常。因为不符合小端法的IEEE规则。

经过稍微修改后正常

function swap(v:Double): Int64; overload;
begin
  swap64Ex(v, Result);
end;

返回的值用Int64来存放这样就好了。

 

注意不要把一个不是Double类型的数据直接强制转换成Double类型,因为Double是有标准字节格式的,当然Single一样。

目录
相关文章
|
30天前
|
人工智能 前端开发 JavaScript
拿下奇怪的前端报错(一):报错信息是一个看不懂的数字数组Buffer(475) [Uint8Array],让AI大模型帮忙解析
本文介绍了前端开发中遇到的奇怪报错问题,特别是当错误信息不明确时的处理方法。作者分享了自己通过还原代码、试错等方式解决问题的经验,并以一个Vue3+TypeScript项目的构建失败为例,详细解析了如何从错误信息中定位问题,最终通过解读错误信息中的ASCII码找到了具体的错误文件。文章强调了基础知识的重要性,并鼓励读者遇到类似问题时不要慌张,耐心分析。
|
2月前
|
存储 NoSQL 关系型数据库
什么是 CAP 理论和 BASE 理论,看这一篇就够了
什么是 CAP 理论和 BASE 理论,看这一篇就够了
53 12
|
5月前
|
C++ 安全
提高安全性,优雅实现拷贝与交换:C++中的Copy-and-Swap惯用法
拷贝并交换(Copy-and-Swap)是C++中实现赋值操作符和异常安全拷贝构造函数的技巧,涉及使用拷贝构造函数创建临时对象,然后交换数据以确保安全。C++11之前的通用方法,在C++11后可利用移动语义和右值引用优化。示例代码展示了如何运用此方法。
|
11月前
|
vr&ar
visionOS空间计算实战开发教程Day 4 初识ImmersiveSpace
沉浸式空间为内容提供了一个无界的区域,可在空间内控制内容的大小和摆放位置。在获取用户的授权后,我们还可以使用开启了沉浸空间的ARKit来将内容集成到周遭环境中。例如,可以使用ARKit场景重建来获取家具的网格(mesh)及其附近的对象,让内容可以与网格进行交互。
112 0
|
存储 安全 Linux
【看表情包学Linux】磁盘基础知识 | CHS 寻址 | 逻辑扇区 LBA | 索引节点 inode | 伪删除 inode bitmap 1→0
【看表情包学Linux】磁盘基础知识 | CHS 寻址 | 逻辑扇区 LBA | 索引节点 inode | 伪删除 inode bitmap 1→0
174 0
|
Linux C语言
Linux内存管理:详解malloc()和free()函数的用法与原理
在C语言中,动态内存分配是一项关键任务,而`malloc()`和`free()`函数则是实现动态内存分配的重要工具。本文将深入介绍这两个函数的使用方法、内部原理以及注意事项,帮助读者更好地理解如何进行内存管理。
1145 0
|
存储 网络协议 开发者
[oeasy]python0074[专业选修]字节序_byte_order_struct_pack_大端序_小端序
[oeasy]python0074[专业选修]字节序_byte_order_struct_pack_大端序_小端序
72 0
|
Linux
内核笔记](四)——内核常见调试手段(printf、dump_stack、devmem)
内核笔记](四)——内核常见调试手段(printf、dump_stack、devmem)
263 0
内核笔记](四)——内核常见调试手段(printf、dump_stack、devmem)
|
存储 C++
C/C++零散知识点汇总之sizeof()和strlen()
C/C++零散知识点汇总之sizeof()和strlen()