首页 > 代码库 > 关于SimpleMsgPack中swap引发的问题大端法和小端法研究笔记
关于SimpleMsgPack中swap引发的问题大端法和小端法研究笔记
今天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
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一样。
关于SimpleMsgPack中swap引发的问题大端法和小端法研究笔记
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。