二进制相关基础知识(2)

简介: 二进制相关基础知识

补码互补对称:

image.png


案例


public class Demo04 {
  public static void main(String[] args) {
    /*
     *  测试补码的互补对称现象: -n = ~n+1  min除外
     *  ~ 取反计算:将2进制每个位进行翻转 1变0,0变1
     */
    int n = 20;
    int m = ~n + 1; //m为n的相反数 -20
    System.out.println(m);
    //分析运算过程:
    System.out.println(Integer.toBinaryString(n)); 
    System.out.println(Integer.toBinaryString(~n)); 
    System.out.println(Integer.toBinaryString(~n+1)); 
    /*
       n   =    00000000000000000000000000010100  16+4   = 20  
       ~n  =    11111111111111111111111111101011  -1-4-16=-21
       ~n+1=    11111111111111111111111111101100  -1-1-2-16=-20
     */
  }
}



int类型的编码:

image.png


经典面试题目:


System.out.println(~80+1);

1

上述代码的输出结果:( B ) A.-79 B.-80 C.-81 D.-82


System.out.println(~-80+1);

1

上述代码的输出结果:( B ) A.79 B.80 C.81 D.82


System.out.println(~80);

1

上述代码的输出结果:( C ) A.-79 B.-80 C.-81 D.-82


4 二进制运算符


常见运算符


取反  ~

与运算 &

或    |

右移位 >>>

数学又移位 >>

左移位 <<


与运算 & (逻辑乘法)


基本运算规则:有0则0


0 & 0 -> 0

0 & 1 -> 0

1 & 0 -> 0

1 & 1 -> 1


运算时候讲两个数字对齐位数,对应位进行与计算。


举个例子:


          7   7    d   d    d   e    7   d    

n      =   01110111 11011101 11011110 01111101

m      =   00000000 00000000 00000000 11111111  mask 掩码

k=n&m      00000000 00000000 00000000 01111101  


如上代码的运算意义:n的最后8位数被截取下来,存储到了k中,经常用于截取数据部分位计算,这种计算称为“掩码(Mask)运算”。 其中m称为“掩码”,按照1的个数是8个称为8位掩码。


代码案例:


int n = 0x77ddde7d;

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      =  01101111 11101111 00110111 10110111

n>>>1  =  001101111 11101111 00110111 1011011

n>>>2  =  0001101111 11101111 00110111 101101

n>>>8  =  00000000 01101111 11101111 00110111

b3=(n>>>8) & 0xff;

         00000000 00000000 00000000 00110111


代码:


int n = 0x6fef37b7;

int m = n>>>1;

int k = n>>>2;

int g = n>>>8;

int b1 = (n>>>24) & 0xff;

int b2 = (n>>>16) & 0xff;

int b3 = (n>>>8) & 0xff;

int b4 = (n>>>0) & 0xff;

//按照2进制输出 n m k g b3

//如何计算 b1 b2 b3 b4 ?


将一个整数拆分为4个字节


             b1       b2       b3       b4

n       =  01110111 11011101 11011110 01111101

b1      =  00000000 00000000 00000000 01110111

b2      =  00000000 00000000 00000000 11011101

b3      =  00000000 00000000 00000000 11011110

b4      =  00000000 00000000 00000000 01111101

案例:

int b1 = (n>>>24) & 0xff;

int b2 = (n>>>16) & 0xff;

int b3 = (n>>>8) & 0xff;

int b4 = (n>>>0) & 0xff;


| 或运算(逻辑加法)


基本规则:有1则1


0 | 0 -> 0

0 | 1 -> 1

1 | 0 -> 1

1 | 1 -> 1


将两个2进制数字对齐位数,对应位进行或运算。


举个例子:


n          = 00000000 00000000 00000000 10110101

m          = 00000000 00000000 10110111 00000000

k = n|m      00000000 00000000 10110111 10110101


如上案例的意义:n和m两个数进行拼接,k中低8位数是n,高8位数是m


案例:


int n = 0xb5;

int m = 0xb700;

int k = n | m;

//按照2进制检测 n m k


<< 左移位计算


将2进制数字的整体向左移动,高位自动溢出,低位补0;


举个例子:


n        = 10111011 10101110 10000011 11010001

m = n<<1   0111011 10101110 10000011 110100010

k = n<<2   111011 10101110 10000011 1101000100

g = n<<8   10101110 10000011 11010001 00000000


代码:


int n = 0xbbae83d1

int m = n<<1;

int k = n<<2;

int g = n<<8;

//按照2进制输出 n m k g


将4个字节数据合并为一个int整数:


b1      =  00000000 00000000 00000000 01110111

b2      =  00000000 00000000 00000000 11011101

b3      =  00000000 00000000 00000000 11011110

b4      =  00000000 00000000 00000000 01111101


b1<<24  =  01110111 00000000 00000000 00000000

b2<<16  =  00000000 11011101 00000000 00000000

b3<<8   =  00000000 00000000 11011110 00000000

b4      =  00000000 00000000 00000000 01111101

合并:n = (b1<<24)|(b2<<16)|(b3<<8)|b4

             b1       b2       b3       b4

n       =  01110111 11011101 11011110 01111101


代码:


int b1 = 0x77;

int b2 = 0xdd;

int b3 = 0xde;

int b4 = 0x7d;

int n = (b1<<24)|(b2<<16)|(b3<<8)|b4;

//按照2进制检测 b1 b2 b3 b4 n


移位计算的数学意义 和 >>


2进制中,数字整体向左移动一次扩大2倍(溢出情况除外)


举个例子:


n         = 00000000 00000000 00000000 00000110     6

m = n<<1    0000000 00000000 00000000 000001100    12

k = n<<2    000000 00000000 00000000 0000011000    24

...


经典面试题目:


表达式 n * 8 可以替换为( n<<3 ) (被乘数是2的整次幂)


>> 称为数学右移位计算,运算结果相当于数学除法(溢出时候向小方向取整数)


>>移位时候: 正数高位补0,负数高位补1


>>> 移位时候:无论正负,高位都补0


举个例子(负数)


n     =  11111111 11111111 11111111 10011100   -1-1-2-32-64 -100

m =n>>1  111111111 11111111 11111111 1001110   -1-1-16-32    -50

k =n>>2  1111111111 11111111 11111111 100111   -1-8-16       -25

g =n>>3  11111111111 11111111 11111111 10011   -1-4-8        -13

f =n>>>1 011111111 11111111 11111111 1001110   正数


>>>逻辑右移位计算,不管符号,将数字整体向右移动


>> 数学右移位计算,有符号移位,符合数学计算结果


如果为了替代数学计算就使用 >>

如果为了数字整体向右移动,不考虑数学结果,就使用 >>>

经典面试题目:


表达式 n / 8 (n>0)可以替换为( n>>3 ) (除数是2的整次幂)


目录
相关文章
【面试题精讲】如何将二进制转为十六进制
【面试题精讲】如何将二进制转为十六进制
|
7月前
|
人工智能 BI C++
C/C++基础知识——字符串(一)
C/C++基础知识——字符串
120 0
|
7月前
|
安全 数据安全/隐私保护 C++
C/C++基础知识——字符串(二)
C/C++基础知识——字符串
267 0
|
7月前
|
算法 C++
C/C++基础知识——字符串(三)
C/C++基础知识——字符串
241 0
|
7月前
|
自然语言处理 Rust 编译器
【0到1的设计之路】从C语言到二进制程序
【0到1的设计之路】从C语言到二进制程序
100 0
|
存储 网络协议 C语言
C语言进阶教程(大小端存储)
C语言进阶教程(大小端存储)
107 0
二进制基础
二进制基础
63 0
|
存储 安全 编译器
>>>C语言<<< 前言、什么是C语言 、标准格式 、数据类型 、数据的输入和输出 、结束语
>>>C语言<<< 前言、什么是C语言 、标准格式 、数据类型 、数据的输入和输出 、结束语
117 0
|
存储 C语言
【C语言_复习_学习第二课】什么是进制?进制之间应该如何转换
什么是进制?在我们的生活中处处充满进制,一天是24个小时、一个小时是60分钟、一分钟是60秒、一个星期一共7天........还有大家听说过半斤八两这个词语吗?也就是说买半斤东西也就是八两,一斤也就是十六两,满16进一位这就是十六进制。我今天就当一次小学老师来考考你,5+8等于多少(我没有在和大家开玩笑)你会说等于13,你的回答就是十进制也就是满十进一,而在计算机中数字都是以二进制(只有1和0)存储的也就是满二进一位,当然也有八进制(从0到7)、十六进制(从0到F)都是类似的,八进制满八进一位,十六进制满十六进一位(其中十六进制10用A来表示,11-B、12-C、13-D、14-E、15-F)
121 0
|
存储 编译器 C语言
【C语言】简述大小端存储
【C语言】简述大小端存储
432 0