关于java中byte的相关问题

来源:互联网 发布:高斯步枪 知乎 编辑:程序博客网 时间:2024/06/15 21:55
public class Test {
public static void main(String[] args)throws Exception{
InetAddress b=InetAddress.getLocalHost();
System.out.println("地址:"+b.getHostAddress());
System.out.println("机器名:"+b.getHostName());
byte[] ba=b.getAddress();
for(byte bb:ba) {
System.out.println("byte形式:"+bb);
}


}

}

发现运行程序时:

地址:192.168.31.125
机器名:YR170814-UEWZ
byte形式:-64
byte形式:-88
byte形式:31
byte形式:125


出现了两个负数,以前不是很在意这个问题,查了相关资料,知道原因了。

因为在java的二进制是以补码形式。

byte的表示范围是-128~127

大家都知道byte是八位,八位中的首位是符号位:0表示正,1表示负


如:(以下均为补码)
00000001------>1

00000010------>2

10000000------>-128

111111111------>-1


直观上的感觉第一位决定符号,后7位,决定大小


比如上面

10000000------>-128

111111111------>-1


-128的后七位0000000 当然要比-1的后七位1111111要小,所以-128当然要比-1小,所以负数最小的是-128,因为后七位最小只能是0000000;

负数最大的是-1,因为后七位最大是1111111,。



接下来就要讲凭什么


10000000------>-128

111111111------>-1



这是因为在java的二进制是以补码形式。


什么叫做补码,这里就要提到什么是原码,反码,补码


1.1.1. 原码

所谓原码就是符号位加上数字的二进制表示,int为例,第一位表示符号 (0正数 1负数)简单期间一个字节表示

+7的原码为: 00000111
 -7的原码为: 10000111

对于原码来说,绝对值相等的正数和负数只有符号位不同。

1.1.2. 反码

一个数如果为正,则它的反码与原码相同;一个数如果为负,则符号位为1,(符号位不变化,其余位数取反)。

换言之 该数的绝对值取反(绝对值取反各位都取反)
为了简单起见,我们用1个字节来表示一个整数:
     +7的反码为:00000111
     -7的反码为: 11111000

1.1.3. 补码

补码:一个数如果为正,则它的原码、反码、补码相同;一个数如果为负,去到反码然后加1。(反码加1就是补码)为了简单起见,我们用1个字节来表示一个整数:
+7的补码为: 00000111
-7的补码为: 11111001

1.1.4. 总结

正数:它的原码、反码、补码相同。

负数:反码符号位不变化,其余位数取反,补码符号位不变化其余各位原码取反(反码)+1换言之 反码+1



有了这些概念我们继续讲,为什么

111111111------>-1

因为这里11111111是补码,我们直接看不出来,我们需要转为原码才能知道,转化方法与原码转为补码的方法倒着走一遍就可以,比如


11111111(补码)先减一】转为11111110(反码)【除符号位不变其余位取反】转为10000001(原码)(符号位1告诉我们是负数,后七位告诉我们绝对值为1)所以原来的数字是-1.这就是为什么111111111------>-1





10000000------>-128

这里的10000000(补码)【先减一】转为01111111(反码)【除符号位不变其余位取反】转为00000000 发现是0;


但你会发现00000000(符号位0,所以原码==补码==反码)已经可以用来表示0了,所以10000000(这个补码是多余的),所以就用它来表示-128,也因为它不满足这个转化关系,所以10000000(补码)没有相对应的反码与原码。




我们回到之前那个程序:

为什么192到byte中变成-64

为什么168到byte中变成-88



我的理解是:192二进制(11000000),java均是以补码形式且Byte是八位,接下来我们转为原码,看看到底是多少。


11000000(补码)先减一】转为10111111(反码)【除符号位不变其余位取反】转为11000000 (原码);符号位1,负数,绝对值2的6次,所以是-64



再来看看168:


168二进制(10101000)(补码)【先减一】转为10100111(反码)【除符号位不变其余位取反】转为11011000 (原码);符号位1,负数,绝对值2的6次+2的四次+2的3次,所以是-88



其实,是因为Byte取八位,把原本第八位用来决定绝对值的1,用来作为符号位1,所以才有了负数的情况