位移
什么是2进制(逢2进一的计数规则)
数字: 0 1
权: 128 64 32 16 8 4 2 1 基数2的幂
10进制计数(逢10进1)
数字: 0 1 2 3 4 5 6 7 8 9
权: 1000 100 10 1 基数10的幂
2进制与10进制直接的转换,可以表示相同的数字(相同的个数)
计算机内部没有10进制,只有2进制!
Java 利用算法(方法)支持了10进制!
Integer.toString() 将内存中的2进制转换为10进制的字符串进行输出
Integer.parseInt() 将10进制的字符串,转换为2进制的数字。
java 会自动的调用这两个方法,实现转换. 所以感觉上Java是认识10进制的!
补码:是一个算法:将正数模拟为有符号数
节省了成本:利用正数表示负数
补码是软件实现的!
补码的算法原理:
4位数补码为例:阐述补码的工作原理
规定:超过4位数自动溢出
补码的缺点:
补码是有范围数,不能超范围计算. 超范围,得到溢出的结果
解决问题:(适当解决)扩充范围!
补码的对称性:-n = ~n + 1
- 是补码的特性,不是数学规则!
- 两个极值无效 (max min 0 -1)
16进制:16进制用于2进制的缩写!
如何缩写:每4位2进制可以缩写为一个16进制数(16进制规则:逢16进1)
数字:0 1 2 3 4 5 6 7 8 9 a b c d e f
权:256 16 1
程序员在书写2进制时候,采用16进制形式!如: 0xb5
2进制的计算
~ 取反运算(相对于二进制取反)
| 或运算(逻辑加)
0|0=0;
0|1=1;
1|0=1;
1|1=1;
案例:
n = 00000000 00000000 11100101 00000000
| m = 00000000 00000000 00000000 11011101
--------------------------------------------
i = 00000000 00000000 11100101 11011101
n=0xe500;
m=0xdd
x=n|m;//e5dd
如上案例的逻辑意义:将n和m拼接为i或运算经常用于数据的拼接!
& 与运算
0&0=0;
0&1=1;
1&0=0;
1&1=1;
案例:
n = 00100100 10100100 00111101 11010110
& m = 00000000 00000000 00000000 11111111
-------------------------------------------
i = 00000000 00000000 00000000 11010110
n = 0x24a43dd6;
m = 0xff;
i = n & m; // i = 0xd6
如上运算的逻辑意义:将n的后8位截取下来
>>> 逻辑右移运算
数字的每个数字向右移动,左侧填充0
n = 00101011 10110101 01010010 11001101
m=n>>>1=000101011 10110101 01010010 1100110
m=n>>>2=0000101011 10110101 01010010 110011
m=n>>>8=00000000 00101011 10110101 01010010
思考如下代码的逻辑意义:?
int b1 = n & 0xff;
int b2 = (n>>>8) & 0xff;
int b3 = (n>>>16) & 0xff;
int b4 = (n>>>24) & 0xff;
如上代码的逻辑意义是将n拆分为4段!
将一个int拆分为4个byte数
>> 数学右移位运算
正数时候高为0时候 >> 高位补0
负数时候高为1时候 >> 高位补1
n = 010111010100101010100010111010110 正数
n = 110111010100101010100010111010110负数
<< 左移动运算
int b1 = 0xcd;
int b2 = 0x55;
int b3 = 0xb5;
int b4 = 0x2b;
将b1 b2 b3 b4 拼接为一个int,如何做
i= b1 | (b2<<8) | (b3<<16) | (b4<<24);
移位运算的数学意义:
10进制移动小数点运算
122748. 小数点向右移动一位
1227480. 原始数据*10(基数)
如果小数点位置不动,可以看做数字向左移动:10进制数字向左移动一次结果是原始数据*10!
在2进制中:2进制数字向左移动一次结果是原始数据*2!
n*2 = n<<1
n*4 = n<<2
n*8 = n<<3
>> 运算的数学意义:原数据/2, 结果向小方向取整数。
5 >> 1 -> 2
-5 >> 1 -> -3
-5>>>1 结果没有数学意义!
运算的用途: 将数字(int long)进行拆分为byte,将byte合并为数字 int long