大端(Big Endian)/小端(Little Endian)字节序
大端(Big Endian)/小端(Little Endian)字节序
参考文章:
- 阮一峰的网络日志:理解字节序(图片取自这里)
- Wikipedia:Endianness
- How to teach endian
大端字节序 与 小端字节序
在计算机中存在这样一个问题:如何表示各种各样的数据?
对于图片等文件来说,有固定的格式文档参考。
而对于整数来说,计算机应该如何表示?
它的定义一定包括整数的大小、是否带符号以及符号是什么、使用什么编码格式表示(一般都是二进制补码),还有很重要的一点:字节顺序。
字节应该从右向左读还是从左向右读呢?
这种读取的顺序就称为:字节序(Byte-order / Endianness)
字节序分为两种:大端字节序(Big Endian,从左向右)和小端字节序(Big Endian,从右向左)
换句话说
大端字节序高位字节在前,低位字节在后
小端字节序低位字节在前,高位字节在后
从一个十六进制数字0x1234
开始:
大端字节序
大端字节序是人类处理自然语言的做法,符合人类从左向右读的阅读习惯。
在这种规范下,十六进制数会先存储0x12作为高字节,接下来存储0x34。
小端字节序
低位字节在前,高位字节在后,也就是会以0x3412的形式存储。
注意!
字节序是以字节为单位定义的,在一个字节中,两个半字节仍然是以大端的形式存在。
疑问?
为什么要区分字节序?这样复杂的意义是什么?
小端字节序的意义
小端字节序对于逻辑电路更有效率。逻辑电路先处理低位字节更有效率,因为计算都是从低位开始的,计算机中的内部处理逻辑都是使用小端字节序。
但是,大多数的网络协议和文件格式都是大端字节序,这样对用户更加友好。
既然有区分,在使用时肯定要使用一定的解析规则,下面进行简要介绍。
字节序的处理
对于大端字节序,计算机先读到的是高位字节,后读到的是低位字节。而小端字节序恰好相反。
字节序的处理:只有在读取的时候才需要区分字节序,其他情况都不需要处理。
处理器读取外部数据时,必须知道数据的字节序才可以将其转化成正确的值。接下来就可以正常使用这个值,不需要再考虑字节序。而向外部设备写数据的时候,也不需要考虑字节序,正常写入一个值即可,外部设备会自己处理字节序的问题。
例如,处理器读入一个16位整数
大端字节序会按照如下方法转值:
x = buf[offset] * 256 + buf[offset+1];
其中buf
是整个数据块在内存中的起始地址,offset
表示偏移量,也就是正在读取的位置。第一个字节乘以256,再加上第二个字节,就是大端字节序的值,这个式子可以用逻辑运算符改写。即:
x = buf[offset]<<8 | buf[offset+1];
编译器总是将乘2的幂转换成移位指令,这样更加方便!左移八位,即在后面添加8个0。
小端字节序会按照如下方法转值:
x = buf[offset+1] * 256 + buf[offset];
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);
原文地址:https://www.cnblogs.com/folm/p/12004711.html
- Android点击EditText文本框之外任何地方隐藏键盘的解决办法
- Spark 1.4为DataFrame新增的统计与数学函数
- 《Redis设计与实现》读书笔记(三十三) ——Redis排序命令sort的实现
- 高通HAL层之Sensor HAL
- Android Data Binding(数据绑定)用户指南
- Android 禁止Viewpager左右滑动功能
- 高通Audio中ASOC的machine驱动
- 《Redis设计与实现》读书笔记(三十五) ——Redis 二进制位数组及SWAR汉明重量算法
- Android TabWidget底部显示
- 《Redis设计与实现》读书笔记(三十六) ——Redis 慢查询日志实现
- 概率学中的随机变量与分布
- 神马?SQL竟然可以解脑筋急转弯的题目?
- android中一些特殊字符(如:←↑→↓等箭头符号)的Unicode码值
- 基于SpringBoot的任务管理平台v1.0正式发布
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 基于Linux搭建Apache网站服务配置详解
- CentOs下手动升级node版本的方法
- 详述Linux中Firewalld高级配置的使用
- CentOS7安装PHP7 Redis扩展的方法步骤
- centos7下rsync+crontab定期同步备份
- 你可能不知道的一些linux文件权限管理方法
- 原来SqlSession只是个甩手掌柜?真正干活的是谁?
- Linux下的定时任务和延时任务的详解
- 使用 chkconfig 和 systemctl 命令启用或禁用 Linux 服务的方法
- Packetdrill的简明使用手册
- linux操作系统下配置ssh/sftp和权限设置方法
- linux把php升级到5.6的实操方法
- Linux sudo 漏洞可能导致未经授权的特权访问
- 在Linux中如何轻松删除源安装的软件包
- linux系统 java环境变量的配置方法