java Int 二进制原理与 +、-、>>、>>>、^、&计算

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zhangyong01245/article/details/83715717

java Int 二进制原理与 +、 -、 >>、>>>、<<、^、&计算

    最近在复习Java 基础时二进制原理,展开了一定的了解,先纪录一下,便于后续学习

Int 二进制

  1. int 类型默认是有符号的,最高位 0 表示 正数, 1 表示负数。 例如:
      5 的二进制:0101 ;
      -5的二进制:1101 ;

  2. 原码、补码 反码 理解:
    a、原码:一个正数,按照绝对值大小转换成的二进制数;一个负数按照绝对值大小转换成的二进制数,然后最高位补1,称为原码 比如:
      5 的原码 : 0101 ;
      -5的原码: 1101 ;

    b、反码:正数的反码与原码相同,负数的反码为对该数的原码除符号位外各位取反。
      5 的反码 : 0101 ;
      -5的反码: 1010 ;

    c、补码:正数的补码与原码相同,负数的补码为对该数的原码除符号位外各位取反,然后在最后一位加1.(即反码 +1)
      5 的补码: 0101 ;
      -5的补码:1011 ;

  3. 主要知识点:
    ①正数的反码和补码都与原码相同。
    ②而负数的反码为对该数的原码除符号位外各位取反。
    ③负数的补码为对该数的原码除符号位外各位取反,然后在最后一位加1
    ③ 补码的补码为原码

Int 二进制相加 或 相减

  1. 计算原理:
    a、减法 可以视为 +负数来处理,所以整体可视为 两个数相加减法

    b、二进制相加 一般是以补码的形式相加,将最终结果在取补码 : X(补) + Y(补) = Z(补); X 表示十进 制转成的二进制,Y表示十进制转成的二进制,Z 表示两个二进制相加后的结果,符号位也进行计算,超出位数舍弃(比如X,Y一个3位,一个5位,最终结果Z应该是5位,注意此处涉及到溢出问题,下面会讲到)。

    c、例如 4 + 3 = 7 可视为: 0100 + 0011 = 0111 ( 7 )

    d、注意 两个数字相加时 应保持二进制的位数相同,位数不够时在符号位之后添加0补齐。

  2. 二进制相加溢出问题:
    a、按照(1)中所讲的计算原理:当计算 (-6) + (-2) = -8 时: -6 的原码–>反码–>补码:1110–>1001–>1010, -2的原码–>反码–>补码:110–>101–>110, 为保持和-6的二进制一样位宽,因此2的原码–>反码–>补码:1010–>1101–>1110;两个补码相加结果为:11000,结果的位数比原先的多出了一位,此处最左边的1,是会被自然丢弃的(就是不要了)。再看结果,对1000求补码(其实可以看出它就是0)。这和我们想要的-8有天壤之别。原因是这里出现了溢出!!!

    b、溢出的定义: 那上面-2-6为例,即1110 + 1010,两个二进制相加时把每个的第一位数(红色字体)相加取其进位数(1+1 进位数是1) 和每个的第二位数相加的进位数(1+0进位数是0)进行比较如果不相同,则会发生溢出,-2-6则判断发生了溢出,反之,不会发生溢出
    例如以下二进制计算:
      1011 + 1111 – > 前两位的进位数: 1 和 0 -----> 溢出;
      1111 + 0111 —> 前两位的进位数: 0 和 1 -----> 溢出;
      1011 + 0101 —> 前两位的进位数 : 0 和 0 ------> 不会溢出;
      1111 + 0001 —> 前两位的进位数 : 0 和 0 ------> 不会溢出;
    注意:前两位的进位数: 10表示负溢出,01表示正溢出,大家可以再去了解其概念与原理。

c、当出现此种情况时解决方案:
  将 -2的二进制写成10010(比开始多一位),-6的二进制写成10110。在进行补码计算:
     -2: 原码–>反码–>补码: 10010–>11101–>11110;
     -6: 原码–>反码–>补码: 10110–>11001–>11010;
     11110 + 11010 = 111000 -->11000 其补码为11000对应的二进制位: -8,
d、计算结束

>>、>>>、<<、<<< 表达的含义 及运算的原理:

  1. 如下 Java代码所示:
public static void main(String[] args) {
    /**
     *  1、<< : 左移运算符:符号位不变,高位溢出,低位补0,对补码进行操作
     *  2、十进制--> 二进制补码 --->操作补码 --> 将补码取补码 -->十进制
     *  3、过程(二进制):
     *    a、6 的二进制补码(32位):00000000 00000000 00000000 00000110;
     *    b、向左偏移两位后补码:00000000 00000000 00000000 00011000;
     *    c、补码-->补码-->十进制:24
     *  4、打印结果为: 24
     */
    System.out.println("6 << 2 ===== " +(6 << 2));

    /**
     *  1、<< : 左移运算符: 符号位不变,高位溢出,低位补0,对补码进行操作
     *  2、十进制--> 二进制补码 --->操作补码 --> 将补码取补码 -->十进制
     *  3、过程(二进制):
     *    a、6 的二进制补码(32位):11111111 11111111 11111111 11111010;
     *    b、向左偏移两位:11111111 11111111 11111111 11101000;
     *    c、补码-->补码-->十进制:-24
     *  4、打印结果为: -24
     */
    System.out.println("-6 << 2 ===== " +(-6 << 2));

    /**
     *  1、>> : 右移运算符: 符号位不变,低位溢出,高位用符号位补高位,对补码进行操作
     *  2、十进制--> 二进制补码 --->操作补码 --> 将补码取补码 -->十进制
     *  3、过程(二进制):
     *    a、6 的二进制补码(32位):00000000 00000000 00000000 00000110;
     *    b、向左偏移两位:00000000 00000000 00000000 00000001;
     *    c、补码-->补码-->十进制:1
     *  4、打印结果为:1
     */
    System.out.println("6 >> 2 ===== " +(6 >> 2));

    /**
     *  1、>> : 右移运算符: 符号位不变,低位溢出,高位用符号位补高位,对补码进行操作
     *  2、十进制--> 二进制补码 --->操作补码 --> 将补码取补码 -->十进制
     *  3、过程(二进制):
     *    a、-6 的二进制补码(32位):11111111 11111111 11111111 11111010;
     *    b、向左偏移两位:11111111 11111111 11111111 11111110;
     *    c、补码-->补码-->十进制:-2
     *  4、打印结果为:-2
     */
    System.out.println("-6 >> 2 ===== " +(-6 >> 2));

    /**
     *  1、>>> : 无符号右移(无符号的意思是将符号位当作数字位看待): 低位溢出,高位补0,对补码进行操作
     *  2、十进制--> 二进制补码 --->操作补码 --> 十进制
     *  3、过程(二进制):
     *    a、6 的二进制补码(32位):00000000 00000000 00000000 00000110;
     *    b、向左偏移两位:00000000 00000000 00000000 00000001;
     *    c、补码-->十进制:1
     *  4、打印结果为:1
     */
    System.out.println("6 >>> 2 ===== " +(6 >>> 2));

    /**
     *  1、>>> : 无符号右移(无符号的意思是将符号位当作数字位看待): 低位溢出,高位补0,对补码进行操作
     *  2、十进制--> 二进制补码 --->操作补码 -->十进制
     *  3、过程(二进制):
     *     a、-6 的二进制补码(32位):11111111 11111111 11111111 11111010;
     *    b、向左偏移28位:00000000 00000000 00000000 00001111;
     *    c、补码-->十进制:15
     *  4、打印结果为:15
     */
    System.out.println("-6 >>> 28 ===== " +(-6 >>> 28));
    
}

位异或运算(^),位与运算符(&):

  1. 位异或运算(^):
    a、运算规则是:两个数转为二进制,然后从高位开始比较,如果相同则为0,不相同则为1。
    b、比如:8^11 : 8转为二进制是1000,11转为二进制是1011.从高位开始比较得到的是:0011.然后二进制转为十进制,就是Integer.parseInt(“0011”,2)=3;

  2. 位与运算符(&)
    a、运算规则:两个数都转为二进制,然后从高位开始比较,如果两个数都为1则为1,否则为0。
    b、比如:129&128 : 129转换成二进制就是10000001,128转换成二进制就是10000000。从高位开始比较得到,得到10000000,即128.

最后:
大家有更好的简介请评论探讨,博主会及时更正

猜你喜欢

转载自blog.csdn.net/zhangyong01245/article/details/83715717