title: 大小端字节序的转换 date: 2015-08-27 22:07:25 tags: C/C++ category: 技术笔记 — 本文参考了Ocean’s Caprice的《[c/c++ ]字节序与大小端转换》   今天在移植OspServer过程中出现文件传输停滞的问题。经导师指点,可能是字节序的问题。因为目标机PowerPC采用的是大端字节(big-endian)存储方式,而平时一般Intel和AMD的CPU采用的都是小端字节(little-endian)。   大端字节序,也叫网络字节序,一般规定不同系统间通信一律采用网络字节序。所谓大端字节序,就是将数据高位存放在内存低位。也就是内存的地址是由低到高的顺序,而数据的字节却是由高到低。如一个long型数据0x12345678,它在内存中存储方式:

| 内存地址 | 数据位 | | :——– | ——–:| | 0x0029f458 | 0x12 | | 0x0029f459 | 0x34 | | 0x0029f45a | 0x56 | | 0x0029f45b | 0x78 |   小端字节序,内存的地址是由低到高的顺序,数据的字节也是由低到高。0x12345678在内存中存储方式:

内存地址 数据位
0x0029f458 0x78
0x0029f459 0x56
0x0029f45a 0x34
0x0029f45b 0x12

整数字节序转换

//对应int32大小的成员 的转换 范例   
int32_t swapInt32(int32_t value)  
{  
	return ((value & 0x000000FF) << 24) |  
            ((value & 0x0000FF00) << 8) |  
             ((value & 0x00FF0000) >> 8) |  
              ((value & 0xFF000000) >> 24);  
}

浮点数字节序转换

  浮点数的内部结构相对比较复杂,但仍然可以把浮点数当作整数转换字节序,因为字节始终是字节,可以使用c++的reinterpret_cast操作把浮点数诠释为整数,这称为类型双关(type_punning),或者使用一个简便的方法是使用union。

union intWithFloat  
{  
     int32_t m_i32;  
     float   m_f32;  
}  
  
float swapFloat32(float value)  
{  
     intWithFloat i;  
     i.m_i32 = value;  
     i.m_f32 = swapInt32(i.m_i32)  
     return i.m_f32;  
}