日常开发工作中,很难用到二进制运算,编程语言已经帮我们做好处理了,除非研究的就是底层技术,比如硬件开发,这是避不过去的,但是你如果还想深入研究一番,本篇论文就值的你看。
在开发的时候需要获取本地地址,java中提供了api
String hostAddress = InetAddress.getLocalHost().getHostAddress();
byte[] address = InetAddress.getLocalHost().getAddress();
第一个返回字符串192.168.1.7,第二个返回字节数组,一共4个数分别为-64 -88 1 7。
我们知道一个字节8位,如果是无符号类型,取值范围为0~256。如果是有符号类型,取值范围为-128 ~ 127 。正常我们需要获取的是192,明显超过了127,说明肯定越界了,从而字节数为-64,java肯定为我们做了处理。我就去找源码如下:
public String getHostAddress() {
return numericToTextFormat(getAddress());
}
static String numericToTextFormat(byte[] src)
{
return (src[0] & 0xff) + "." + (src[1] & 0xff) + "." + (src[2] & 0xff) + "." + (src[3] & 0xff);
}
其中numericToTextFormat(byte[] src)的src就是上面我们说的字节数组,对每个字节数做了src[0] & 0xff运算就正常了,我们拿-64来举例,看看是怎么运算的。
计算机中存储的是数字的补码,我们复习一下计算机组成原理:
第一位表示符号,其余各位表示数字位。
正数的原码、补码、反码都一样。
负数的自己去查吧
-64 原码:11000000(2)
反码:10111111
补码:11000000
0xff为16进制 -> 0000000011111111,因为int类型为64位前面一堆0,我不想写了省略掉了。
来做一下运算src[0] & 0xff
11000000
11111111
11000000,前面还有一堆0,因为编程中,小类型变为大类型是自动转化的,如byte到int,不会丢失准确度。
0011000000(2) -> 192
正好可以得出这个结果
下面再来说一下如何越位的,以及怎么处理。
byte 8字节,且存储的是有符号数
会存在1000000和00000000,也就-0和正0,计算机为了多表示一个数,用1000000表示-128,从而说明了byte的范围为-128至127.
本来是192,存储到byte中就变成了-64,说明越界了,那怎么越界的?
11000000(2),前面一堆0,由int转为byte会失精度,只会截取8位,第一位作为符号位,从而为-64。
今天复盘了一下计组中的二进制的运算,希望对你有帮助。
以后会把工作中遇到的问题定期分享,帮助自己也是帮助他人。