二进制和位运算
2进制
什么2进制?计算机为什么使用2进制
逢2进1的计数规则
电子设备设计成处理2进制,其成本最优。
计算机如何解决人类和计算机直接的机制矛盾
所有编程语言都是一种人和计算机之间的翻译工具,人的数组语言翻译成二进制给计算机读取,然后把计算机的二进制数据翻译成人类的语言呈现出来。

16进制
16进制用于缩写(简写)2进制,将2进制从后向前 每4位数转换为1位16进制。
补码
补码: 将固定位数的2进制数分一半作为负数使用的编码规则。其目的是为了解决负数计算问题。
以4位补码为例研究补码的编码规则! 将4位2进制分一半作为负数使用。
这种规则下减法也可以用加法来计算,相邻两个数顺时针方向增加1。

二进制的换算
从0到最大值的计算无需多说,就按二进制来算就行。
负数的二进制换算方法:负数可以跟-1比较,-1是所有位都为1,拿到一个二进制负数,只要看它比-1小多少就可以算出它对应的十进制数:
11111111 11111111 11111111 11101010
11111111 11111111 11111111 111111111(-1)
以上面这个数为例,上面这个数比-1少了(1+4+16=21),所以它的十进制就是-1-21=-22.
相反数的对应关系
在这种编码规则下还有个特点,就是一个数求反再加一就是它的相反数,即:n=~n+1;
经典面试题目:
System.out.println(~100+1);
如上代码的输出结果:
A. -99 B.-100 C.-101 D.-102
答案:B
100 00000000 00000000 00000000 01100100
~100 11111111 11111111 11111111 10011011 -101
~100+1 11111111 11111111 11111111 10011100 -100
System.out.println(~100);
如上代码的输出结果:
A. -99 B.-100 C.-101 D.-102
答案:C
2进制运算(位运算)
位运算符有:
与 & 、 或| 、异或^、取反~ 、左移位<< 、
数学右移位(有符号右移)>> 、逻辑右移位(无符号右移)>>>
与计算 & (逻辑乘法)
计算规则:
0 & 0 -> 0
0 & 1 -> 0
1 & 0 -> 0
1 & 1 -> 1
有0则0
计算时候,将两个数对其位数,将齐的数字进行 “&” 计算
举个栗子:
n= 01110100 01111101 00101111 01101011
m= 00000000 00000000 00000000 11111111
k=n&m 00000000 00000000 00000000 01101011
如上计算的意义:k是n的最后8位数!也就将n的最后8位切下放到k中。
称为掩码(mask)计算,其中m称为掩码(mask),m有8个1时候称为8位掩码
代码:
int n = 0x747d2f6b;
int m = 0xff;// 0xf 0x3f 0xffff
int k = n&m;
//按照2进制输出 n m k 的值
右移位计算 >>>
规则: 将数字整体向右移位,高位补,低位自动溢出
举个栗子:
n= 01101001 11111010 01110000 01010101
m=n>>>1 001101001 11111010 01110000 0101010
k=n>>>2 0001101001 11111010 01110000 010101
g=n>>>8 00000000 01101001 11111010 01110000
代码:
int n = 0x69fa7055;
int m = n>>>1;
int k = n>>>2;
int g = n>>>8;
//将整数n拆分为4个字节 b1 b2 b3 b4
int b1 = (n>>>24) & 0xff;
int b2 = (n>>>16) & 0xff
int b3 = (n>>>8) & 0xff;
int b4 = n & 0xff;
应用:与运算和右移配合可以实现用某种长度的掩码把数据分段截取,数据传输经常这样使用
或计算 | (逻辑加法)
基本规则:
0 | 0 -> 0
0 | 1 -> 1
1 | 0 -> 1
1 | 1 -> 1
有1则1
将两个数对齐位置,对应数字进行 或计算
举个栗子:
n = 00000000 00000000 11001101 00000000 n=0xcd00
m = 00000000 00000000 00000000 11011111 m=0xdf;
k =n|m 00000000 00000000 11001101 11011111 k=n|m
b1= 00000000 00000000 00000000 11011101 b1=0xdd;
b2= 00000000 00000000 00000000 01101110 b2=0x6e;
b3= 00000000 00000000 00000000 10111011 b3=0xbb;
b4= 00000000 00000000 00000000 10101101 b4=0xad;
//左移运算符
b1<<24 11011101 00000000 00000000 00000000
b2<<16 00000000 01101110 00000000 00000000
b3<<8 00000000 00000000 10111011 00000000
b4= 00000000 00000000 00000000 10101101
x= 11011101 01101110 10111011 10101101
b1 b2 b3 b4
x= (b1<<24)|(b2<<16)|(b3<<8)|b4
应用:或运算配合左移刚好可以完成数据的拼接,也是在数据传输中使用
移位计算的数学意义
复习: 移动小数点计算
如: 52439.
小数点向右移动一次: 524390. 数字扩大10倍
小数点向右移动二次: 5243900. 数字扩大100倍
假如小数点不动,数字向左移动:数字向左移动一次,数字扩大10倍
2进制时候: 数字向左移动:数字向左移动一次,数字扩大2倍
128 64 32 16 8 4 2 1
0 0 1 1 0 0 1 0
0 1 1 0 0 1 0 0 <<1
逻辑右移位 >>> 数学右移位 >> 的区别
数学右移位 >> 计算的结果是: 数据除以2向小取整数的结果
区别:
逻辑右移位 >>> 移位时候,正数高位补0 负数高位补0,单纯将数字向右移动,用于数字的拆分计算
数学右移位 >> 移位时候,正数高位补0 负数高位补1,用于替代特殊除法计算
举个栗子:
n= 11111111 11111111 11111111 11001110 -50
m=n>>1 111111111 11111111 11111111 1100111 -25
k=n>>2 1111111111 11111111 11111111 110011 -13
x=n>>>1 011111111 11111111 11111111 1100111
y=n>>>2 0011111111 11111111 11111111 110011
逻辑右移位 >>> 单纯将数字向右移动,用于数字的拆分计算
数学右移位 >> 用于替代特殊除法计算