不知道大家是不是像我之前一样一看到二进制丶十六进制就头大,更别说位运算了,也不知道位运算的作用是啥,索性花了一些时间整理出这些知识点。 我们知道程序中的所有数在计算
| 不知道大家是不是像我之前一样一看到二进制丶十六进制就头大,更别说位运算了,也不知道位运算的作用是啥,索性花了一些时间整理出这些知识点。 我们知道程序中的所有数在计算机内存中都是以二进制的形式储存的。位运算就是直接对整数在内存中的二进制位进行操作。 而二进制有8位(最低)丶 16位 丶32位 丶64位甚至更多,我们要怎样进行 这令人愉悦的折磨呢 位运算呢? X进制与二进制既然位运算操作的是二进制数,就需要先把其他数转换成二进制. 如果你已经知道如何进制转换可以跳到位运算这段。 首先看下十进制转二进制 125转换成二进制是01111101,计算方法很简单正十进制数除以二,得到的商再除以二,依次类推直到商为零时为止,然后在旁边标出各步的余数,最后倒着写出来,再根据实际高位补零,即除二取余,倒序排列,高位补零。 
 将余数倒置则是1111101,然后我们发现结果只有7位数,而二进制最低位是8位,所以进行高位补零之后得到他的最终结果01111101 
 二进制转X进制知道了十进制转二进制,那你知道反过来该怎么算吗? 将二进制中的位数分别与对应的值相乘,然后相加得到的就为十进制 我们看到01111101这个二进制,它是一个八位数,从低位(最右边)开始计算,分别乘对应的值,最后相加,那如何区分一个二进制是正数还是负数呢?当然是看首位,首位为1为负数,首位为0为正数,这里的首位指的是二进制的头一个数,而不是位数的最低位(计算是从低位开始,判断正负则看首位)。 
 这样就得出了结果125,然后首位为0则是正125。 其他进制转二进制8进制丶16进制 2进制等相互转换其实是很简单的,因为其有对应关系 
 负数转二进制上面说的是正整数转二进制的方法,那么负数呢? 二进制取反,然后对结果再加一 如何理解呢,我们已经算出125的二进制(8位情况下)表示是01111101,取反的意思则是0变成1,1变成0,结果是10000010,然后加一,而二进制逢二进一,所以得出得结果为10000011,所以-125的二进制在8位的显示中为10000011。 
 当定义八位(byte)-125时它代表的八位二进制是10000011,当你反过来算时得到的值131>八位(byte)的范围,所以他并不能用byte表示。 
 所以当10000011用来表示八位二进制是-125 (byte) 1000 0011 = -125 (short)0000 0000 1000 0011 = 131 (short)1111 1111 1000 0011 = -125 以上就是关于各进制与二进制之间的转换了。 位运算接下来我们看一下如何进行位运算,位运算到底有什么用呢? 
 
 10001100 01110011 位与(&)位与即如果两个位进行比较两位同时为1,结果才为1,否则结果为0。 例如: 125 & 7 
           125   &    7
 二进制: 01111101 & 00000111
位与比较:    
0 1 1 1 1 1 0 1
---------------
0 0 0 0 0 1 1 1
| | | | | | | |
× × × × × √ × √
| | | | | | | |
0 0 0 0 0 1 0 1
结果: 125&7 = 0000 0111 = 5位或(|)位或即如果两个位进行比较两位同时为0,结果才为0,否则结果为1。 例如: 125 | 7 
           125   |    7
 二进制: 01111101 | 00000111
位或比较:    
0 1 1 1 1 1 0 1
---------------
0 0 0 0 0 1 1 1
| | | | | | | |
√ × × × × × × ×
| | | | | | | |
0 1 1 1 1 1 1 1
结果: 125|7 = 0111 1111 = 7异或(^)位异或即如果两个位进行比较相同取0,不同取1。 例如: 125 ^ 7(java中^代表异或) 
           125   ^    7
 二进制: 01111101 ^ 00000111
位异或比较:    
0 1 1 1 1 1 0 1
---------------
0 0 0 0 0 1 1 1
| | | | | | | |
√ × × × × √ × √
| | | | | | | |
0 1 1 1 1 0 1 0
结果: 125^7 = 0111 1010 = 122异或的几条性质: 1、交换律 编程算法中的作用:交换两个数(利用性质) 
public void Swap(int  &a,  int  &b){  
  if  (a  !=  b){  
    a  ^=  b; //a=a^b
    b  ^=  a; //b=b^(a^b) = (b^b)^a = a 
    a  ^=  b; //a=(a^b)^a = (a^a)^b = b
        }  
}右移(>>)将一个数的各二进制位全部右移若干位,正数左补0,负数左补1,右边丢弃。 125>>3 
           125   >>    3
右移:    
0 1 1 1 1 1 0 1
---------------
0 0 1 1 1 1 1 0 |1     >> 1
0 0 0 1 1 1 1 1 |0 1   >> 2
0 0 0 0 1 1 1 1 |1 0 1   >> 3
^ ^ ^ 
正数补0负数补1
结果: 125>>3 = 0000 1111 = 15
等价与 125/2的3次方的商左移(<<)同样的,左移则是将一个运算对象的各二进制位全部左移若干位(左边的二进制位丢弃,右边补0)。 125>>3 
           125   >>    3
右移:    
      0 1 1 1 1 1 0 1
      ---------------
    0|1 1 1 1 1 0 1 0  << 1
  0 1|1 1 1 1 0 1 0 0  << 2
0 1 1|1 1 1 0 1 0 0 0  << 3
                ^ ^ ^
                 补0
结果: 125<<3 = 1110 1000 = -24(八位)       
      125<<3 = 1110 1000 = 1000(十六位)
相当:125*2的3次方(若左移时舍弃的高位不包含1)无符号右移(>>>)无符号右移则始终补0,不考虑正负数。 总结:
 MENMORY TOAST >>>>>> | 
2022-04-23
2023-04-23
2022-10-16
2022-08-26
2020-04-20