二进制

标签: 二进制

计算机内部一切都是2进制!

变量, 数据都是2进制:

数据类型: byte short int long float double boolean char

案例:

什么是二进制?

           逢二进一的计数规律

2进制原理

   


案例:

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

Java 利用算法支持10进制

  1. 底层采用2进制
  2. 人可以使用10进制操作计算机
  3. 利用算法(方法)

    • 将"10进制字符串"转换为2进制

      int Integer.parseInt(String)
      
    • 将2进制(int)转换为"10进制字符串"

      String Integer.toString(int) 
      

16进制

逢16进1 的计数规律, 在计算机编程中用于简写2进制!

每个16进制的数字可以缩写4位2进制数.

案例:


补码

为了将2进制数据分出一半来表示负数, 设计了补码:

案例:

/**
 * 补码 
 */
public class Demo03 {
    public static void main(String[] args) {
        for(int i=-10; i<=10; i++){
            System.out.println(
                Integer.toBinaryString(i));
        }

        for(long i=-10; i<=10; i++){
            System.out.println(
                Long.toBinaryString(i)); 
        }
    }
}


补码的最大值和最小值:


因为补码正负数互补对称, 故称为补码:


面试题 1:

int n = 0xffffffff;
System.out.println(n);
如上代码输入结果:
A.2147483647 B.-2147483647 C.2147483648 D.-2147483648 E.-1

>答案:E

面试题 2:

int max = Integer.MAX_VALUE;
System.out.println(Integer.toBinaryString(max));
如上代码输入结果:
A.11111111111111111111111111111111
B.1111111111111111111111111111111
C.10000000000000000000000000000000
D.1000000000000000000000000000000

>答案:B

面试题 3:

System.out.println(~800+1); 
代码输出结果: -800

System.out.println(~800); 
代码输出结果: -801

System.out.println(~-800); 
代码输出结果: 799

2进制运算符

~ 取反 & 与运算 | 或运算

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

& 与运算

按位与运算 (逻辑乘法)

规则:

1 & 1 = 1
0 & 1 = 0
1 & 0 = 0
0 & 0 = 0 

案例:

n = 01001000 00100101 11010101 01111010
m = 00000000 00000000 00000000 11111111  : mask
n&m-----------------------------------------
k   00000000 00000000 00000000 01111010

用途: 掩码(Mask:面具)运算, 可以将一个数拆分

int n = 0x4825d57a;
int m = 0xff;
int k = n&m;
//输出n m k 2进制

掩码运算的数学意义

32 16 8 4 2 1 
1  0  0 1 1 1  n
0  0  0 0 1 1  m 
n&m = n%4

m = 0x3;
for(int i=0; i<20; i++){
    int x = i&m;
    int y = i%4;
    System.out.println(x+","+y);
}


32 16 8 4 2 1 
0   0 1 0 0 1  i = 5 6 7 8 9 10
0   0 0 0 1 1  m

i & m = 1   ==  i % 4 = 1

案例:

/**
 * 掩码运算相当于2整次幂的余数
 * 
 *  n&0x1  等于  n%2
 *  n&0x3  等于  n%4
 *  n&0x7  等于  n%8
 *  n&0xf  等于  n%16
 */
public class Demo06 {
    public static void main(String[] args) {
        int m = 0x3;
        for(int i=0; i<20; i++){
            int x = i&m;
            int y = i%4;
            System.out.println(x+","+y);
        }
    }
}

经典题目:

优化运算 n>0, n%8 为(  )
答案: n&0x7

| 或运算

按位或运算 (逻辑加法)

规则:

0 | 0 = 0
0 | 1 = 1
1 | 0 = 1
1 | 1 = 1

案例:

n = 00000000 00000000 00000000 10010110
m = 00000000 00000000 11000110 00000000
n|m ---------------------------------------
    00000000 00000000 11000110 10010110

颜色拼接: 将3个颜色分量合并为一个RGB色(int)

int r = 00000000 00000000 00000000 11000101
int g = 00000000 00000000 00000000 10010010
int b = 00000000 00000000 00000000 00100111

int r = 00000000 11000101 00000000 00000000
int g = 00000000 00000000 10010010 00000000
int b = 00000000 00000000 00000000 00100111

rgb = r | g | b;

int rgb = 00000000 11000101 10010010 00100111

Java :

int r = 0xc50000;
int g = 0x9200;
int b = 0x27;

int rgb = r|g|b;
JFrame frame = new JFrame();
frame.setSize(200,300);
frame.setBackground(new Color(rgb));

移位运算

>>> 逻辑右移位

将2进制数字向右移动, 低位移出, 高位补0

规则:

    高位                            低位
n = 00100101 01111001 10010011 00100011
    2   5    7   9    9   3    2   3
m = n>>>1
m = 000100101 01111001 10010011 0010001

案例: 拆分rgb为单独颜色分量

int rgb = 00000000 01111001 10010011 00100011

int r = (rgb >>> 16) & 0xff;
int g = (rgb >>> 8) & 0xff;
int b = rgb & 0xff;

案例:

public class Demo08 {

    public static void main(String[] args) {
        //逻辑右移位运算
        int n = 0x25799323;
        int m = n>>>1;
        System.out.println(
            Integer.toBinaryString(n));
        System.out.println(
            Integer.toBinaryString(m));
        //将RGB色拆分为3个颜色分量 r,g,b  
        int rgb = 0x799323;
        //          r g b
        int r = (rgb>>>16) & 0xff;
        int g = (rgb>>>8) & 0xff;
        int b = rgb & 0xff;

        System.out.println(
                Integer.toBinaryString(rgb));
        System.out.println(
                Integer.toBinaryString(r));
        System.out.println(
                Integer.toBinaryString(g));
        System.out.println(
                Integer.toBinaryString(b));

        //将颜色分量r,g,b合并为一个RGB颜色

        int color = (r<<16)|(g<<8)|b;
        System.out.println(
                Integer.toBinaryString(color));
    }
}

移位运算的数学意义

引子: 10进制移动小数点运算

如:    437812.  小数点向右移动
结果     4378120. 差10倍

如果看作小数点不动, 数字向左移动, 数字向左移动一次差10倍

如:     437812.  小数点向右移动
结果     4378120. 差10倍

2进制有同样规律: 数字向左移动, 数字向左移动一次差2倍

n =  00000000 00000000 00000000 00010010  18
m=n<<1
m =  0000000 00000000 00000000 000100100  36
m=n<<2
m =  000000 00000000 00000000 0001001000  72

案例:

/**
 * << 运算案例
 */
public class Demo09 {
    public static void main(String[] args) {
        int n = -18;
        for(int i=0; i<5; i++){
            int m = n<<i;
            System.out.println(m);
            System.out.println(Integer.toBinaryString(m));
        }
    }
}

>>> 区别 >>

正数(符号位是0) >>> 和 >> 没有区别 负数(符号位是1) >>> 高位补0, >> 高位补 1, 高位补1时候保持是负数, 符合数学/2规律, 溢出时候向小方向取整数

案例:

/**
 * >>> 与 >> 的区别
 */
public class Demo10 {
    public static void main(String[] args) {
        int n = -18;
        for(int i=0; i<5; i++){
            int m = n>>i;
            System.out.println(m);
            System.out.println(Integer.toBinaryString(m));
        }
    }
}

经典面试题

优化 n*8 为 ( ? )
答案: n<<3

2进制运算的用途:

互联网, 文件都是按照Byte为单位传输数据.



版权声明:本文为qq_41264674原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_41264674/article/details/80368567