浅谈编程中的位操作

昨天有同学谈起网络编程中各种奇怪的位运算,所以单独整理一下实践中的位运算,权当复习。

基本的位运算 位运算符包括与,或,非,异或,这属于common sence了,只要给出一段01二进制串,每个程序员应该都可以处理。

类型

无论编程语言中的类型怎样,只要涉及网络通信,存储,最终都会涉及一个字节的转换过程。对于java来说,主要考虑整型,浮点型,字符串,其中整型和字符串是最常用的。

  • 整型,在java都是有符号数,根据不同类型都有固定的字节长度,并采用补码形式。关于补码,可以看看这篇文章关于2的补码
  • 浮点型,包括单精度和双精度,采用IEEE的浮点表示法,比较少使用,可以通过深入理解计算机系统2.4.2 IEEE浮点表示,这个章节了解浮点数的二进制形式。
  • 字符串,java的字符串采用unicode字符表示,存储的时候通常得考虑字符编码,所谓字符编码,就是字符和字节的对应关系。有些api会允许直接写入或读取字符串,但是对底层采用的字符编码要心里有底。

大端法,小端法

例如一个数,0x12345678, 存储到0x01到0x04这4个字节,那么有2种方式,一种是12345678,叫大端法,一种是78563412,叫小端法。就是看最低有效位(78)是在高地址(04)还是低地址(01)。这方面找了个文章理解字节序,可以了解一下。

tcpip协议规定网络传输统一采用大端法。指的是ip,tcp等协议的头部信息。见TCP/IP详解5.2章节 应用层网络协议有时会看到这个描述,没说明的话,默认也是按大端法开发,比较适应阅读。

数据转换

应用层协议上经常会涉及一些数据位的转换,但是有时不能类型强制转换,例如:某个协议上用一个无符号byte,例如b,那么可以通过b & 0xff得到一个int。这个类型强转的区别在于它会保留符号位。