• 数字的大小端转换


    简介

    在不同的系统中,当最最基础的数据存在问题的时候,这是最让人头疼的问题。但是,世界就是爱和我们开玩笑,不是么?在芯片中,有两种方式存储数据:

    • 大端,也叫Big-Endian,同样有个很感人的名字Motorola
    • 小端,也叫little-Endian,同样也有一个和我们息息相关的名字Intel
      至于,为什么这么叫,具体的自己去查找。

    用在什么场合?

    一般小端,会用在数据的存储上,而大端用在数据的传输。前者也叫主机序,后者也叫网络字节序,当然,也不是绝对。至于用什么,当然根据自己的爱好了,当然和协议也有很大的关系。

    如何把主机上的数据通过网络传输?

    这其中,涉及到很多问题,主机序列是否和网络字节序匹配,这里,分开说明。

    主机字节序和网络字节序相同

    • 准备工作

       //type define uchar(8bit) & uword(16bit) & uint(32)
       typedef unsigned char uchar;
       typedef unsigned short uword;
       typedef unsigned int uint;
       //Network data buffer
       #define BUFFER	(0x08)
       //data receved buffer
       uchar data[BUFFER];
       //data
       uint num;
      
    • 转换代码,如果转换为uint型:
      - 接收
      Value = *(uint*)&data[0];
      - 发送
      data[0] = *(uchar*)#

    如果存在差异

    可以利用如下的宏来进行转换

    #define lit_big_TransShort(a_data) (((a_data) & 0x00ff) << 8 | ((a_data) & 0xff00) >> 8)
    #define lit_big_TransLong(a_data) (((a_data) & 0xff000000) >> 24 | ((a_data) & 0x000000ff) << 24)
    #define lit_big_TransWord(a_data) lit_big_TransShort(a_data)
    #define lit_big_TransInt(a_data)  (lit_big_TransLong(a_data) | (lit_big_TransShort((a_data) >> 8) << 8))
    
    • 如果有差异,可以经过以下两个步骤:
    1. Value = *(uint*)&data[0];
    2. Value = lit_big_TransInt(Value);
    • 或者
    1. num = lit_big_TransInt(num);
    2. data[0] = *(uchar*)&num;

    以上的方式在某些地方存在问题,正如上一篇文章描述的问题:

    某些芯片,由于架构的原因,并不支持奇数地址指针的某些数据获取。所以,如果通过这种暴力的指针类型转换是存在问题的,所以,只有提供如下的函数来进行转换。

    最好的解决办法,就是自己编写一个类似于网络字节序转主机字节序的函数。
    以下是这几个函数:

    • htons()
    • htonl()
    • ntohs()
    • ntohl()
      记忆规则就是“h/n”表示host or Network,加上to这个向量标识,"s/l"表明转换大小:short/long.
  • 相关阅读:
    @RequiresPermissions 注解说明
    接活博客
    通知postNotificationName 消息传递详解
    VentureBeat:2012年度最佳移动网页设计字体
    ios企业版IDP的申请及“In House”发布
    cocos2d游戏开发教程资源
    iOS开发设计素材篇2
    推荐给 iOS 设计师的工具和资源
    推荐一位牛人的博客
    在网上接外包
  • 原文地址:https://www.cnblogs.com/ply616/p/5525229.html
Copyright © 2020-2023  润新知