关于二进制的补码,反码,正负数表示以及 Java 代码测试

用户头像
Zexho
关注
发布于: 2020 年 09 月 08 日
关于二进制的补码,反码,正负数表示以及Java代码测试

Java负数的计算过程

java中最高位表示符号位,0表示正数,1表示负数

根据十进制推算二进制

以-5为例子

  1. -5的原码:1000 0101

  2. 求反码 : 1111 1010 ,符号位不进行取反

  3. 求补码(+1):1111 1011

所以-5用二进制表示为1111 1011

根据二进制逆推十进制

10001010为例子

  1. 获取补码(-1操作)10001010 - 1 = 10001001

  2. 获取反码10001001 的反码 11110110

  3. 不看符号位,算出大小1110110 对应的值为 118,所以10001010的值就是-118

可以看出来,对于负数而言,因为1000 0000 后七位因为要取反,所以后七位越大反而绝对值越小,例如1111 1111 等于-1,而1111 1110 等于-2

那么对于负数而言 1000 0000 就是绝对值最大,相对值最小的了,等于-128

为什么要这样设计

首先在计算机中减法实际上是加法,2-1 == 2 + (-1),那么进行推理一下

如果都用原码

2 的原码:0000 0010

-1 的原码: 1000 0001

2 + (-1)= 10000 0011

答案是是 -3,答案错误

如果正数用原码,负数用补码

事例1

2的原码:0000 0010

-1的补码: 1111 1111

相加 =0000 0001 ,就等于1

事例2

10的原码:0000 1010

-20的补码: 1110 1100

10 + (-20) = 1111 0110 等于-10

为什么要用补码表示负数,而不是反码

或者换个说法,为什么要进行+1操作

如果不用补码,而用反码

1的原码: 0000 0001

-1的反码:1111 1110d

1 + (-1) = 1111 1111 = -128

很明显答案错误

那么为什么要进行+1操作,如果你对1111 11111 +1可以发现 = 0001 0000 0000,而因为byte的大小只有8位,第9位要舍弃也就是0000 0000

因为负数最高位存在一个1,也就是说负数天然要比正数多一个1,对于正数而言,你就得额外+1才能保证正数和负数是一样大的。

关于byte取值范围

byte的取值范围为-128 ~ 127

为什么负值要大于正值?

对于最大值很容易得出:0111 1111 就等于127

但是负数不同,在1000 0000这个特殊情况下符号位是参与运算的,也就是说,1000 0000 是最小值,转化成十进制就是-128了

Java代码测试

public static void main(String[] args) {
byte x1 = (byte)0b00000010;
byte x2 = (byte)0b11111111;
System.out.println("x1 = " + x1);
System.out.println("x2 = " + x2);
System.out.println("x1 + x2 = " + (x1 + x2));
byte x3 = (byte)0b11111110;
System.out.println("x3 = " + x3);
byte negative20 = (byte)0b11101100;
System.out.println("negative20 : " + negative20);
byte negative10 = (byte)0b11110110;
System.out.println("negative10:"+negative10);
}



发布于: 2020 年 09 月 08 日 阅读数: 31
用户头像

Zexho

关注

芝兰生于幽谷,不因无人而不芳 2019.02.15 加入

https://github.com/zouzhihao-994

评论

发布
暂无评论
关于二进制的补码,反码,正负数表示以及Java代码测试