zoukankan      html  css  js  c++  java
  • 002_大端和小端的区别

    一、大小端出现原因

           计算机系统是以字节为单位的,每个地址单元都对应着一个字节,一个字节为8bit。但对于位数大于8位的处理器,如16位或32位/64位的处理器,由于寄存器宽度大于一个字节,那么必然存在一个如何将多个字节安排的问题。因此就导致了大端存储模式和小端存储模式的出现。

    二、为什么会有小端字节序?

    答案是,计算机电路先处理低位字节,效率比较高,因为计算都是从低位开始的。所以,计算机的内部处理都是小端字节序。

    但是,人类还是习惯读写大端字节序。所以,除了计算机的内部处理,其他的场合几乎都是大端字节序,比如网络传输和文件储存。

    三、

    计算机硬件有两种储存数据的方式:大端字节序(big endian)和小端字节序(little endian)。

    举例来说,数值0x2211使用两个字节储存:高位字节是0x22,低位字节是0x11

    • 大端字节序:高位字节在前,低位字节在后,这是人类读写数值的方法。
    • 小端字节序:低位字节在前,高位字节在后,即以0x1122形式储存。

    32位整数的求值公式也是一样的。

    
    /* 大端字节序 */
    i = (data[3]<<0) | (data[2]<<8) | (data[1]<<16) | (data[0]<<24);
    
    /* 小端字节序 */
    i = (data[0]<<0) | (data[1]<<8) | (data[2]<<16) | (data[3]<<24);

    四、

    同理,0x1234567的大端字节序和小端字节序的写法如下图

     五、

    对于整型、长整型等数据类型,Big endian 认为第一个字节是最高位字节(按照从低地址到高地址的顺序存放数据的高位字节到低位字节);而 Little endian 则相反,它认为第一个字节是最低位字节(按照从低地址到高地址的顺序存放据的低位字节到高位字节)。

    例如,假设从内存地址 0x0000 开始有以下数据: 
    0x0000         0x0001       0x0002       0x0003 
    0x12            0x34           0xab           0xcd
    如果我们去读取一个地址为 0x0000 的四个字节变量,若字节序为big-endian,则读出结果为0x1234abcd;若字节序为little-endian,则读出结果为0xcdab3412。

    如果我们将0x1234abcd 写入到以 0x0000 开始的内存中,则Little endian 和 Big endian 模式的存放结果如下: 
    地址           0x0000         0x0001        0x0002          0x0003
    big-endian   0x12           0x34            0xab            0xcd 
    little-endian  0xcd           0xab            0x34            0x12

    一般来说,x86 系列 CPU 都是 little-endian 的字节序,PowerPC 通常是 big-endian,网络字节顺序也是 big-endian还有的CPU 能通过跳线来设置 CPU 工作于 Little endian 还是 Big endian 模式。

    对于0x12345678的存储:

    小端模式:(从低字节到高字节)
    地位地址 0x78 0x56 0x34 0x12 高位地址

    大端模式:(从高字节到低字节)
    地位地址 0x12 0x34 0x56 0x78 高位地址

    六、大端小端检测方法(2015款MAC pro跑的如下代码)

    #include <iostream>
    /*return 1: little-endian, return 0: big-endian*/
    int checkCPUendian()
    {
        union
        {
            unsigned int a;
            unsigned char b;
        }c;
        c.a = 1;
        return (c.b == 1);
    }
    using namespace std;
    int main() {
        //---------------------- (1)第一种查询方式 ----------------------//
        cout<<checkCPUendian()<<endl;//输出=> 1,表示小端(Intelx86处理器)
        //---------------------- (2)第二种查询方式 ----------------------//
        int i = 1;
        char *p = (char *)&i;
        if(*p == 1)
            printf("Little Endian");//输出=> Little Endian,表示小端(Intelx86处理器)
        else
            printf("Big Endian");
        return 0;
    }
    

      

    Reference:

    https://www.ruanyifeng.com/blog/2016/11/byte-order.html

    https://www.cnblogs.com/luxiaoxun/archive/2012/09/05/2671697.html

  • 相关阅读:
    13 Memcached 永久数据被踢现象
    PHP 学习内容
    12 Memcached 缓存无底洞现象
    Memcached 常用的方法
    PHP Memcached 面试题
    11 Memcached 缓存雪崩现象
    JQ报表插件
    (2.1)mysql升级与降级
    基于binlog恢复工具mysqlbinlog_flashback
    如何查看正在执行sql的语句及其父语句调用?如何查看正在执行SQL的具体参数值与执行计划?xml执行计划转为图形计划
  • 原文地址:https://www.cnblogs.com/itcomputer/p/14127076.html
Copyright © 2011-2022 走看看