二进制

逢二进一的计数规则,是计算机底层采用的计数规则.

原理:

1.png

1.png

案例:

public static void main(String[] args) {
        /**
         * 展示一个整数的本质-- 2进制
         **/
        int n = 50;
        System.out.println(n);//110010 -> "50"  
        //toBinaryString方法本质是展示n在内存中的
        //2进制存储情况
        System.out.println(Integer.toBinaryString(n));  

        for(int i=0;i<50; i++) {
            System.out.println(Integer.toBinaryString(i));
        }
    }

关于容量大小

2.png

2.png

  1. 位bit,2进制数的一个数字称为一个位,如:整数是32位数
  2. 字节Byte, 8位,最初用于表示计算机处理的一个"字符", 称为字节. 泛指8位2进制,称为一个字节. 如: 整数4字节. 字节是计算机中衡量数量的最常用单位.
  3. 字节数量表示方式, 经常用于表示计算机中零件的容量:

数量: 1024Byte = 1KByte = 1K
1024KByte = 1MByte = 1M(兆)
1024MByte = 1GByte = 1G
1024GByte = 1TByte = 1T
1024TByte = 1PByte = 1P

硬盘和U盘的容量: 1000K = 1M

  1. 字符: Java字符类型16位,支持常用字符范围(基本编码平面)0~65535, 两个字节.
  2. 网络速率以 bit/s为单位! 如: 100M网络是指每秒传送100Mbit数据.核算为字节需要除以8, 相当于 11M Byte/S 左右

16进制

16进制:是2进制的缩写形式,编程时候用于简化书写2进制. 2进制从最低位到高位每4位2进制可以缩写为一位16进制数.

原理:

3.png

3.png

案例:

public static void main(String[] args) {
        /**
         * Java 7 提供2进制直接量
         * 0b 开头
         * 后面接2进制直接量,只能包含01数字
         * 
         * 16进制用于缩写2进制, 从低位开始,每4位2进制数
         * 缩写为一位16进制数
         */
        //        高位                                                低位
        int n = 0b01101101110111101110001110111010;
        System.out.println(Integer.toBinaryString(n)); 
        n = 0x6ddee3ba;
        System.out.println(Integer.toBinaryString(n)); 

        //利用16进制输出特殊字符
        char c = 0x5abd;
        System.out.println(c); 
        c = 0x2552;
        System.out.println(c); 
    }

补码

补码: 将一个固定位数的2进制数,分一半作为负数,而设计的一套编码规则.
其目的是为了解决 "负数编码" 和计算问题.

以4位数为例子研究补码, 方便研究, 只要推广一下就可以得到32位甚至更高位数补码

4.png

4.png

计算机底层采用2进制补码:

5.png

5.png

案例1

public static void main(String[] args) {
        /**
         * 负数的编码: 补码
         */
        int n = -3;
        System.out.println(Integer.toBinaryString(n));

        int max = 0b01111111111111111111111111111111;
        System.out.println(max);
        System.out.println(Integer.toBinaryString(max));
        max = Integer.MAX_VALUE;
        System.out.println(Integer.toBinaryString(max));

        int min = 0x80000000;
        System.out.println(Integer.toBinaryString(min));
        min = Integer.MIN_VALUE;
        System.out.println(Integer.toBinaryString(min));

        System.out.println(min-max);


        n = -1;
        System.out.println(Integer.toBinaryString(n));  

        n = -11;
        System.out.println(Integer.toBinaryString(n));  
        n = -43;
        System.out.println(Integer.toBinaryString(n));
    }

案例2:

public static void main(String[] args) {
        /**
         * 负数的补码
         */
        for(int i=-50; i<=0; i++) {
            System.out.println(Integer.toBinaryString(i));  
        }
    }

案例3:

public static void main(String[] args) {
        /**
         * long 类型 64位补码
         */
        long max = Long.MAX_VALUE;
        long min = Long.MIN_VALUE;
        long n = -1L;
        long m = -3L;
        System.out.println(Long.toBinaryString(max));
        System.out.println(Long.toBinaryString(min));
        System.out.println(Long.toBinaryString(n));
        System.out.println(Long.toBinaryString(m));

    }

案例4: 互补对称现象

public static void main(String[] args) {
        /**
         * 补码的互补对称现象
         * ~ 取反计算, 将一个数2进制中0变1, 1变0 
         */
        int n = -1;
        int m = ~n;
        System.out.println(m); //0

        //验证互补对称 : -n = ~n + 1, 最小值除外
        n = 1;
        m = ~n + 1;
        System.out.println(m); //-1

        n = 2;
        m = ~n + 1;
        System.out.println(m); //-2

        n = -1;
        m = ~n + 1;
        System.out.println(m); //1

        n = -2;
        m = ~n + 1;
        System.out.println(m); //2

        n = -10000;
        m = ~n + 1;
        System.out.println(m); //10000

        n = 20000;
        m = ~n + 1;
        System.out.println(m); //-20000

        int max = Integer.MAX_VALUE;
        m = ~max+1;
        System.out.println(m); //

        //最小值不成立
        int min = Integer.MIN_VALUE;
        m = ~min+1;
        System.out.println(m); //

    }

2进制计算

2进制运算符

~ 取反运算
& 与
| 或

右移位计算
数学右移位
<< 左移位计算

与计算 &

基本规则 逻辑乘法(有0则0):

0 & 0 -> 0
0 & 1 -> 0
1 & 0 -> 0
1 & 1 -> 1

计算时候需要将两个数, 对齐位置, 对应的位置数字进行与计算

举个栗子:

n = 01111101 10111010 00101011 11100101
m = 00000000 00000000 00000000 11111111 Mask/面具/掩码 8位掩码
k=n&m 00000000 00000000 00000000 11100101

如上计算称为掩码计算, 其作用是将n的最后8位数截取下来, 存储到k中.

代码:

int n = 0x7cba2be5;
    int m = 0xff;
    int k = n&m;
    System.out.println(Integer.toBinaryString(n));
    System.out.println(Integer.toBinaryString(m));
    System.out.println(Integer.toBinaryString(k));

>>> 右移位计算

将一个数的2进制整体位数向右移动, 低位溢出舍弃, 高位补0

举个栗子

n  =    01111101 10111010 00101011 11100101
    m=n>>>1 001111101 10111010 00101011 1110010
    k=n>>>8 00000000 01111101 10111010 00101011

代码:

int n = 0x7cba2be5;
    int m = n>>>1;
    int k = n>>>8;
    //拆分int为4个Byte
    int b1 = (n>>>24) & 0xff;
    int b2 = (n>>>16) & 0xff;
    int b3 = (n>>>8) & 0xff;
    int b4 = (n>>>0) & 0xff;

拆分int为4个Byte

n  =   01111101 10111010 00101011 11100101

    b1 =   00000000 00000000 00000000 01111101
    b2 =   00000000 00000000 00000000 10111010
    b3 =   00000000 00000000 00000000 00101011 
    B4 =   00000000 00000000 00000000 11100101 

    b1 = (n>>>24)&0xff;
    b2 = (n>>>16)&0xff;
    b3 = (n>>>8)&0xff;
    b4 = (n>>>0)&0xff;

| 或

规则: 逻辑加法(有1则1)

0 | 0 -> 0
0 | 1 -> 1
1 | 0 -> 1
1 | 1 -> 1

对齐位置, 对应的数位进行或计算

举个栗子:

n =    00000000 00000000 11011011 00000000
    m =    00000000 00000000 00000000 11011110
    k=n|m  00000000 00000000 11011011 11011110

自行编写案例测试!

合并4个Byte为int

原理:

6.png

6.png

案例:

/**
     * 将4个Byte b1 b2 b3 b4 拼接为一个int
     */
    k = (b1<<24)|(b2<<16)|(b3<<8)|(b4<<0);

    System.out.println(Integer.toBinaryString((b1<<24)));  
    System.out.println(Integer.toBinaryString((b2<<16)));  
    System.out.println(Integer.toBinaryString((b3<<8)));  
    System.out.println(Integer.toBinaryString((b4<<0)));  
    System.out.println(Integer.toBinaryString(k));
最后修改:2021 年 06 月 20 日 06 : 39 PM
如果觉得我的文章对你有用,请随意赞赏