linux 大小端转换ar,大端小端数据读取

前言

前段时间在做二进制数据读取时候,发现读取的数据总是有问题。错误原因就是涉及到大端小端数据读取方式的问题,下面就是将这部分内容做一总结。

什么是大端小端

大小端模式就是存储数据时,数据的高低位是怎么存储在地址的高低位上。

大端模式(Most Significant Byte,MSB):数据的高位,存放在地址的低位,即高位存低位,低位存高位。

小端模式(Least Significant Byte,LSB):数据的高位,存放在地址的高位,即高位存高位,低位存低位。

明显小端模式更符合我们日常记录书写的习惯,pc机一般都是小端模式。

当我们使用的pc机和待读取数据大小端不一致时候,要特别注意,要使用相应的方式进行读取数据,具体方式看下文。

大端小端判断

方法1:

void main(){

short int x;

char x0,x1;

x=0x1122;

x0=((char *)&x)[0]; //低地址单元

x1=((char *)&x)[1]; //高地址单元

printf("x0=0x%x,x1=0x%x",x0,x1);// 若x0=0x11,则是大端; 若x0=0x22,则是小端......

uint32_t i=0x04030201;

unsigned char* cp=(unsigned char*)&i;

if(*cp==1)

printf("little-endian\n");

else if(*cp==4)

printf("big-endian\n");

else

printf("who knows?\n");

}

方法2,通过联合体判断:

#include

union var{

char c[4];

int i;

};

int main(){

union var data;

data.c[0] = 0x04;//因为是char类型,数字不要太大,算算ascii的范围~

data.c[1] = 0x03;//写成16进制为了方便直接打印内存中的值对比

data.c[2] = 0x02;

data.c[3] = 0x11;

//数组中下标低的,地址也低,按地址从低到高,内存内容依次为:04,03,02,11。总共四字节!

//而把四个字节作为一个整体(不分类型,直接打印十六进制),应该从内存高地址到低地址看,0x11020304,低位04放在低地址上。

printf("%x\n",data.i);

}

大端数据读取

二进制数据的存储一般会伴随着一个数据说明文档,在文档中会有数据的存储方式,如:NASA提供的激光高度计数据(IMG后缀),其说明文档里有如下信息,说明该存储方式位大端:

LINES=5632 LINE_SAMPLES = 11520 SAMPLE_TYPE = MSB_INTEGER SAMPLE_BITS = 16 UNIT = METER END_OBJECT = IMAGE

若我们的pc机是小端,在写codes读取数据时候要考虑将大端转小端。

大小端转换

定义宏:

typedef unsigned int uint_32 ;

typedef unsigned short uint_16 ;

大小端转换16位:

#define BSWAP_16(x) \

(uint_16)((((uint_16)(x) & 0x00ff) << 8) | \

(((uint_16)(x) & 0xff00) >> 8) \

)

大小端转换32位:

#define BSWAP_32(x) \

(uint_32)((((uint_32)(x) & 0xff000000) >> 24) | \

(((uint_32)(x) & 0x00ff0000) >> 8) | \

(((uint_32)(x) & 0x0000ff00) << 8) | \

(((uint_32)(x) & 0x000000ff) << 24) \

)

定义函数:

大小端转换16位:

uint_16 bswap_16(uint_16 x)

{

return (((uint_16)(x) & 0x00ff) << 8) | \

(((uint_16)(x) & 0xff00) >> 8) ;

}

大小端转换32位

uint_32 bswap_32(uint_32 x)

{

return (((uint_32)(x) & 0xff000000) >> 24) | \

(((uint_32)(x) & 0x00ff0000) >> 8) | \

(((uint_32)(x) & 0x0000ff00) << 8) | \

(((uint_32)(x) & 0x000000ff) << 24) ;

}

调用方式

sInt 是读取的短整型数据。

sInt=BSWAP_16(sInt); sInt = bswap_16(sInt);

结语

其中代码可以直接用于大小端数据转换。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值