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

msgPack.AsFloat = 2.507182;

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

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

下面是msgPack的标准说明

Float format family stores a floating point number in  bytes or  bytes.
float stores a floating point number in IEEE single precision floating point number format:
+--------+--------+--------+--------+--------+
| 0xca |XXXXXXXX|XXXXXXXX|XXXXXXXX|XXXXXXXX
+--------+--------+--------+--------+--------+ float stores a floating point number in IEEE 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 single precision floating point number
* YYYYYYYY_YYYYYYYY_YYYYYYYY_YYYYYYYY_YYYYYYYY_YYYYYYYY_YYYYYYYY_YYYYYYYY is a big-endian
IEEE double precision floating point number

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

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

procedure swap64Ex(const v; out outVal);
begin
// 7F F5 B8 6F B5 0E // 0E B5 6F B8 F5 7F
PByte(@outVal)^ := PByte(IntPtr(@v) + )^;
PByte(IntPtr(@outVal) + )^ := PByte(IntPtr(@v) + )^;
PByte(IntPtr(@outVal) + )^ := PByte(IntPtr(@v) + )^;
PByte(IntPtr(@outVal) + )^ := PByte(IntPtr(@v) + )^;
PByte(IntPtr(@outVal) + )^ := PByte(IntPtr(@v) + )^;
PByte(IntPtr(@outVal) + )^ := PByte(IntPtr(@v) + )^;
PByte(IntPtr(@outVal) + )^ := PByte(IntPtr(@v) + )^;
PByte(IntPtr(@outVal) + )^ := 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引发的问题大端法和小端法研究笔记的更多相关文章

  1. 大端模式&小端模式、主机序&网络序、入栈地址高低问题

    一.大端模式&小端模式 所谓的“大端模式”,是指数据的低位(就是权值较小的后面那几位)保存在内存的高地址中,而数据的高位,保存在内存的低地址中,这样的存储模式有点儿类似于把数据当作字符串顺序处 ...

  2. 判断CPU是大端还是小端模式

    在小端模式中,低位字节放在低地址,高位字节放在高地址:在大端模式中,低位字节放在高地址,高位字节放在低地址.big-endian和little-endian,51单片机是典型的大端模式,Intel电脑 ...

  3. 用C语言,如何判断主机是 大端还是小端(字节序)

    所谓大端就是指高位值在内存中放低位地址,所谓小端是指低位值在内存中放低位地址.比如 0x12345678 在大端机上是 12345678,在小端机上是 78564312,而一个主机是大端还是小端要看C ...

  4. 转!大端模式&小端模式

    大端模式&小端模式   在C语言中除了8位的char型之外,还有16位的short型,32位的long型(要看具体的编译器),对于位数大于8位的处理器,例如16位或者32位的处理器,由于寄存器 ...

  5. 关于byte[]字节传输的大端和小端小议

    当前的存储器,多以byte为访问的最小单元,当一个逻辑上的地址必须分割为物理上的若干单元时就存在了先放谁后放谁的问题,于是端(endian)的问题应运而生了,对于不同的存储方法,就有大端(big-en ...

  6. 【转】如何判断CPU是大端还是小端模式

    原文网址:http://blog.csdn.net/ysdaniel/article/details/6617458 如何判断CPU是大端还是小端模式 http://blog.sina.com.cn/ ...

  7. C++将整型数据转换成大端或小端存储顺序

    大端和小端的概念参考之前博客: 大端/小端,高字节/低字节,高地址/低地址,移位运算 昨晚帮导师从指令中恢复图像的时候,导师要我转换成raw格式,也就是记录图像像素的二进制序列,然后反复强调让我注意大 ...

  8. 大端和小端(Big endian and Little endian)

    一.大端和小端的问题 对于整型.长整型等数据类型,Big endian 认为第一个字节是最高位字节(按照从低地址到高地址的顺序存放数据的高位字节到低位字节):而 Little endian 则相反,它 ...

  9. 大端和小端(big endian little endian)

    一.大端和小端的问题 对于整型.长整型等数据类型,Big endian 认为第一个字节是最高位字节(按照从低地址到高地址的顺序存放数据的高位字节到低位字节):而 Little endian 则相反,它 ...

随机推荐

  1. 【php+js】用PHP或者JS怎么显示搜索到的关键字高亮,及其文章里包含关键字的一小段

    1.想要实现的效果: 2.思路:小数据量使用 php的正则替换,即[preg_replace()]函数 -->> 支持多个关键词高亮显示,中间参数1和参数2放入对应的数组即可. $titl ...

  2. 【TP3.2.X】(同样适用于OT) 设置单入口index.php文件,区分PC/WAP/Wechat 三个终端

    1.目的:本教程适用于 OneThink1.0.或者TP3.2.X 系列,达到单入口index.php文件,区分PC/WAP/Wechat 三个终端 2.启发至 : http://www.thinkp ...

  3. iOS中coreData的用法

    // // ViewController.m // coredatademo002 // // Created by ganchaobo on 13-6-29. // Copyright (c) 20 ...

  4. grep 和 awk的buffer

    当使用 tail -f test.log | grep "mode" | awk '{print $5}'命令 或者 tail -f test.log | awk '/mode/ ...

  5. 数组问题常用的O(N)算法:单调队列

    求max(a)<min(b)的区间个数 给定两个长度都为N的整型数组a[N]和b[N],求满足如下条件的闭区间个数:在区间[l,r]上,a中的任意元素都比b中的任意元素小. 这个问题是O(N)复 ...

  6. [转]VUE优秀UI组件库合集

    原文链接 随着SPA.前后端分离的技术架构在业界越来越流行,前端的业务复杂度也越来越高,导致前端开发者需要管理的内容,承担的职责越来越多,这一切,使得业界对前端开发方案的思考多了很多,以react.v ...

  7. JavaScript escape() unescape() decodeURI()函数对字符串进行编码解码

    定义和用法 escape() 函数可对字符串进行编码,这样就可以在所有的计算机上读取该字符串. 语法 escape(string) 参数 描述 string 必需.要被转义或编码的字符串. 返回值 已 ...

  8. 基于 CoreText 实现高性能 UITableView

    引起UITableView卡顿比较常见的原因有cell的层级过多.cell中有触发离屏渲染的代码(譬如:cornerRadius.maskToBounds 同时使用).像素是否对齐.是否使用UITab ...

  9. 树莓派进阶之路 (010) - 树莓派raspi-config配置(转)

    经过前面两步我们的树莓派已经正常的工作起来了,但是在真正用它开发之前还需要进行一些列的配置以及软件的安装,这样开发起来才会得心应手,下面我们介绍一下常用的软件和服务 1.配置选项: 树莓派第一次使用的 ...

  10. xtrabackup 源码安装

    安装依赖包:这些依赖包必须要先安装好 # yum install cmake libaio-devel ncurses-devel bzip2-devel libxml2-devel libgcryp ...