在说大小端高低位之前,肯定要说明数据在计算机内是如何存储的。在计算机中,我们将数据分割成了一个一个的字节(byte),而每个字节又有8位(bit)。
一个字节,可以声明为unsigned char型数据,但是有时候不够用,毕竟一个UCHAR也就能表示0-255的数据。所以还会有short型(2字节),int型(4字节),浮点型float(4字节),double型(8字节)等等。其实存在计算机里,数据都还是那些个数据,只是读写的方式因为声明的不同而不同。就好比是一句话一共14个字:今天天气特别好呀我们出去玩吧!假如一个字就是一个字节,那么UCHAR型,我们就是这样从计算机中读写的:今 天 天 气 特 别 好 呀 我 们 出 去 玩 吧! Int型是这样读写的:今天天气 特别好呀 我们出去 玩吧!这些数据在计算机的物理地址上是连续存储的,只是如果我们拿着int型的声明,就硬生生的,一次只能读写4个字节,多一点少一点都不行。就像是那个少一天一秒都不是一辈子的梗一样……
数据都是那些数据,但是有些计算机把值的低位存在低地址,这是小端(little endian)。有些计算机把值的高位存在低地址,这是大端(big endian)。不同CPU厂商大小端又不统一,例如,Motorala6800, PowerPC970等是大端,x86,VAX等是小端。这就要求不同计算机在交互的过程中可能需要进行大小端转换。我之前看了很多帖子学这个的时候有人吐槽说TCP/IP规定使用大端字节序为网络字节序非常任性……
下面贴代码,原理都一样,非常简单,我把short,int,float,double型全贴上以造福以后的懒人。除了double那个都在VC6.0下跑过,可以复制黏贴直接用~
short型:
unsigned short swapShort16(unsigned short shortValue){
return ((shortValue & 0x00FF ) <<8) | ((shortValue & 0xFF00)>>8);
}
int 型(原理都一样!):
int swapInt32(int intValue){
int temp = 0;
temp = ((intValue & 0x000000FF) <<24) +
((intValue & 0x0000FF00) <<8) +
((intValue & 0x00FF0000) >>8) +
((intValue & 0xFF000000) >>24);
return temp;
}
不过float型略有不同,稍微麻烦一点,还需要建一个联合体。这个联合体建立是因为,虽然我们拿着int 型和float型的牌子去找计算机要数据,计算机都给我们四个字节没错。但是它给的方式不同。所以我们要将float型变成int型(不能强制转换傻孩子)然后再进行颠倒。联合体超级好用,我觉得它体现了数据存储的本质,你可以选择一万种方式读写,但是其实数据在联合体肚子里都是一样一样的。
float型:
float swapFloat32(float floatValue){
typedef union SWAP_UNION{
float unionFloat;
int unionInt;
}SWAP_UNION;
SWAP_UNION swapUnion;
swapUnion.unionFloat = floatValue;
swapUnion.unionInt = swapInt32( swapUnion.unionInt);
return swapUnion.unionFloat;
}
double型换一种写法,用一下指针,不然移位移死了……
void swapDouble64(unsigned char *pIn, unsigned char *pOut){
for( int i=0;i<8;i++)
pOut[7-i] = pIn[i];
}
王德福啊,连return都不用了。
关于高低位,虽然通常不用颠倒,该取反取反就行,但是保不齐哪天碰到个什么事情就叫你把一个字节的高低位颠倒一下。反正我就碰到了。一开始觉得这怎么办,系统给了取反你非叫我颠倒,后来想想也是用笨办法就这样移位颠嘛~
Unsigned char bitRevise(unsigned char bitInfo){
Unsigned char bitReturn;
bitReturn = (bitInfo & 0x80)>>7|
(bitInfo & 0x40)>>5|
(bitInfo & 0x20)>>3|
(bitInfo & 0x10)>>1|
(bitInfo & 0x8)<<1|
(bitInfo & 0x4)<<3|
(bitInfo & 0x2)<<5|
(bitInfo & 0x1)<<7;
Return bitReturn;
}