最近在做一个网络通信的模块,众所周知,在网络通信中,大部分大部分数值的表示范围都限于一个字节之内,而一个字节即8位,能够表示256个数字,但通信在传输的过程中都是二进制,即01010组合,这样的话,能够表示的数字位于0000 0000 到1111 1111 之间。8个0即是0,8个1 是255,所以在网络通信中表示意义的数字也就限于0到255之间,比如ip地址,最大255。
网络通信中,数值的表示如下:(这里讲的是一个字节的表示)
0000 0000 = 0
0000 0001 = 1
0000 0010 = 2
0111 1110 = 126
0111 1111 = 127
1000 0000 = 128
1000 0001 = 129
1111 1110 = 254
1111 1111 = 255
可是在java中用流进行读取数字时,存储的都是byte数组,而一个byte占用一个字节,但是表示的范围乃是-128到 127。这样在网络通信中用到的数字和byte就不是一致的,因此需要转换。故而就是因为这个需求,开始了我又重新都计算机存储数字做了一番研究(大学计算机原理学过),下面做个大致介绍。
说先看原码,反码,补码的意思。
原码就是二进制定点表示法,即最高位为符号位,“0”表示正,“1”表示负,其余位表示数值的大小。
反码表示法规定:正数的反码与其原码相同;负数的反码是对其原码逐位取反,但符号位除外。
补码表示法规定:正数的补码与其原码相同;负数的补码是在其反码的末位加1。
在计算机中,数值一律采用补码表示,因为采用补码表示可以简化硬件的操作等等。
这就涉及到补码的计算,以及负数的表示。
规定:
正数直接使用原码表示,负数用补码表示
看例子:
原码 反码 补码 数值
0000 0000 0000 0000 0000 0000 0
0000 0001 0000 0001 0000 0001 1
0000 0010 0000 0010 0000 0010 2
0111 1110 0111 1110 0111 1110 126
0111 1111 0111 1111 0111 1111 127
1000 0000 1000 0000 1000 0000 -128
1000 0001 1111 1110 1111 1111 -1
1000 0010 1111 1101 1111 1110 -2
1000 0011 1111 1100 1111 1101 -3
1111 1110 1000 0001 1000 0010 -126
1111 1111 1000 0000 1000 0001 -127
-128 不存在原码 但是根据补码编排 又正好有个空可以放下,所以 -128 补码直接定义为 10000000 其实-128 看起来是占用的是 -0的位置(规定)。