zoukankan      html  css  js  c++  java
  • 关于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

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

    在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一样。

  • 相关阅读:
    三行代码实现邮件发送
    两种HTTP请求方法:GET和POST的区别
    测试自动化平台 | 测试开发工程师的进阶之路
    测试自动化平台 | 测试开发工程师的进阶之路
    Autotestplat.com 更新了!
    如何规范小开发公司的测试流程。?
    如何规范小开发公司的测试流程。?
    《自动化平台测试开发》出版啦!!!
    后缀数组
    bzoj 3864: Hero meet devil
  • 原文地址:https://www.cnblogs.com/DKSoft/p/4112712.html
Copyright © 2011-2022 走看看