golang大小端字节序
最佳答案 问答题库578位专家为你答疑解惑
为什么要有字节序?
字节序,即字节的排列顺序。在计算机领域中,计算机内存中的字(word)由多个字节(bytes)组成,这些字节的排列顺序叫做字节序。
计算机中电路优先处理低位字节,效率比较高,因为计算机都是从低位开始的,所以计算机内部处理都是小端字节序。但是我们平常读写数值的方法,习惯用大端字节序,所以除了计算机的内部,其他场景大都是大端字节序,比如:网络传输和文件储存时都是用的大端字节序。
小端序(Little Endian):低位字节在低地址,高位字节在高地址。
大端序(Big Endian):高位字节在低地址,低位字节在高地址。
字节序取决于什么?
其实大小端主要由CPU决定,与编程语言、编译器、操作系统这些没有直接关系。
大小端是用于存储的顺序,与存储器(硬件)关系比较大,编译器和操作系统仅仅是配合CPU编译好相应的代码,而不是决定大小端的因素。
一般来说,x86系列CPU都是Little-endian字节序,PowerPC通常是Big-endian字节序。
查看golang整型是大端还是小端?
在 Intel i5 CPU 上执行:
package mainimport ("fmt""unsafe"
)func main() {isLit := IsLittleEndian()fmt.Printf("%t\n", isLit)
}func IsLittleEndian() bool {var value int32 = 1pointer := unsafe.Pointer(&value)pb := (*byte)(pointer)if *pb == 1 {return true}return false
}
输出:
true
以go1.18为例,从go官方目前发布的各系统编译好的包来看,常见的架构都是小端,包括:386、amd64、arm(默认小端)、ppc64le都是小端架构。
整数移位运算结果和字节序有关系吗?
不算大端还是小端,移位运算的结果是一样的,都是按照直观的字面视觉效果移动也就是按照大端字节序理解即可。
移位运算可以看作是一系列的乘2或除2操作。
例如golang的官方包 encoding/binary 里有段代码:
func (littleEndian) PutUint32(b []byte, v uint32) {_ = b[3] // early bounds check to guarantee safety of writes belowb[0] = byte(v)b[1] = byte(v >> 8)b[2] = byte(v >> 16)b[3] = byte(v >> 24)
}
这段代码用了两个和架构无关的运算来实现大小端转换:
1、通过移位运算进行大小端转换,实现架构的兼容。
2、通过整数类型缩小来取最低位byte值,实现架构的兼容。
如果是小端机器这样的操作其实可以用取巧的指针运算,无需进行多次的移位运算:
package mainimport ("encoding/binary""fmt""unsafe"
)func main() {var i uint32 = 0x01020304//官方包var ibyte = make([]byte, 4)binary.LittleEndian.PutUint32(ibyte, i)fmt.Printf("%v\n", ibyte)//指针访问var ibyte2 = make([]byte, 4)pointer := unsafe.Pointer(&i)pb := (*byte)(pointer)ibyte2[0] = *pbpb = (*byte)(unsafe.Pointer((uintptr)(pointer) + 1))ibyte2[1] = *pbpb = (*byte)(unsafe.Pointer((uintptr)(pointer) + 2))ibyte2[2] = *pbpb = (*byte)(unsafe.Pointer((uintptr)(pointer) + 3))ibyte2[3] = *pbfmt.Printf("%v\n", ibyte2)
}
显示:
[4 3 2 1]
[4 3 2 1]
结果和官方包是一致的。
大类型向小类型的强制转换结果和字节序有关吗?
不算大端还是小端,大类型向小类型的强制转换的结果是一样的,都是按照直观的字面视觉效果取最低有效位(最右字节)的值,也就是按照小端字节序理解即可。
在不同架构上运行以下代码,如在ppc和x86机器上运行。
#include <stdio.h>
#include <stdint.h>void main(){//H的16进制是0x48,10进制是72//I的16进制是0x49,10进制是73uint32_t a = 0x48020349;printf("%c\n", *(char*)&a);uint8_t b = (uint8_t)a;printf("%d\n", b);
}
在x86上执行输出:
I
73
在ppc上执行输出:
H
73
可以看到:
按字符处理时,在x86上是小端序,在ppc上是大端序,
在向小类型转换时,都是输出73,也就是都是按的小端序,截取的最低有效位。
--end--
99%的人还看了
相似问题
- JVM:字节码文件,类的生命周期,类加载器
- 网工内推 | 字节原厂,正式编,网络工程师,最高30K*15薪
- Go 以小端字节序修改文件
- UDP端口接收到的字节流如何转为QJsonObject、QJsonArray的方法
- 《2020年最新面经》—字节跳动Java社招面试题
- 计算Qt中的QAudioOutput缓冲区未播放的音频字节数对应时长
- 字节面试:请说一下DDD的流程,用电商系统为场景
- 深入理解JVM虚拟机第二十一篇:详解JVM当中的操作数在栈以及分析操作数栈与字节码指令和执行引擎的关系图解
- 【Linux网络编程_TCP/UDP_字节序_套接字 实现: FTP 项目_局域网聊天项目 (已开源) 】.md updata:23/11/05
- 【项目源码】反编译Java字节码生成源码
猜你感兴趣
版权申明
本文"golang大小端字节序":http://eshow365.cn/6-21148-0.html 内容来自互联网,请自行判断内容的正确性。如有侵权请联系我们,立即删除!
- 上一篇: 10月21日,每日信息差
- 下一篇: SpringMVC(第一个项目HelloWorld))