大端小端数据读取
来源:互联网 发布:cn域名好不好 编辑:程序博客网 时间:2024/06/12 21:43
前言
前段时间在做二进制数据读取时候,发现读取的数据总是有问题。错误原因就是涉及到大端小端数据读取方式的问题,下面就是将这部分内容做一总结。
什么是大端小端
大小端模式就是存储数据时,数据的高低位是怎么存储在地址的高低位上。
大端模式(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<stdio.h> 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);
结语
其中代码可以直接用于大小端数据转换。
博客地址:http://blog.csdn.net/wokaowokaowokao12345/article/details/71534472
参考:
http://blog.csdn.net/xhhjin/article/details/7779716
http://blog.csdn.net/szchtx/article/details/42834391
http://blog.csdn.net/huqinwei987/article/details/23597091
http://www.xuebuyuan.com/2155119.html
- 大端小端数据读取
- 数据存储 大端 和 小端
- 数据的大端小端表示法
- dsp 大端小端
- 大端or小端
- 大端小端
- C++ 大端小端
- 大端与小端
- 大端小端搞清楚
- 大端、小端模式
- 大端,小端
- 大端 小端
- 大端 小端
- 大端小端
- 大端小端
- 大端,小端问题
- 大端 小端判断
- 大端与小端
- WebApi系列--异常处理解决方案
- C#开发Word控件
- 5.OP-TEE+qemu的启动过程分析--run-only目标执行
- 自旋锁和互斥锁区别
- 10.输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。
- 大端小端数据读取
- SQL Server修改表名,字段名,索引名
- LeetCode题解(3)--Longest Substring Without Repeating Characters
- Linux常用指令
- myeclipse+pydev+django环境搭建要点
- VC控件自动排列位置显示
- jsp数据交互(II)
- java获取文件的类型MagicMatch.getMimeType()报错 java.lang.NoClassDefFoundError: org/apache/oro/text/perl/Perl5
- JavaScript如何将多个数据放入一个数组