1. << >> >>>
<< : 带符号 左移运算符 ;高位左移溢出后,舍弃;低位补0;例如 10 << 4 : 00001010 → 10100000 ,转为10进制位 160;简单算法:10*2^4=160;
>> : 带符号 右移运算符 ;移出的部分被舍弃;低位移出(舍弃),高位空位补符号位;
>>> :不带符号 右移运算符;每右移一位等效于 十进制的数 除以 2,余数会被下舍入;低位移出(舍弃),高位空位补零;
补充 :
- 带符号的二进制:最高位表示符号,0代表 正数,1代表负数;
- 计算机中负数用补码表示;正数的补码还是本身;
- 带符号的左移:除符号,全部左移;
- 带符号的右移:除符号外,全部右移,如果最高位为1(负数),用1填补最左边的空位;如果最高位为0(正数),用0填补最左边的空位;
- 不带符号的右移:全部右移,用0填补最左边的空位;
- 原码求补码:原码取反 再 +1;(最高位的符号位保持不变)
- 补码求原码:补码的补码 即为原码;
-4 << 2 : 10000000 00000000 00000000 00000100(原)
→ 11111111 11111111 11111111 11111011(反)
→ 11111111 11111111 11111111 11111100(补)
→ 11111111 11111111 11111111 11110000(带符号左移两位)
→ 10000000 0000000 0000000 00001111(反)
→ 10000000 00000000 00000000 00010000(补)
→ -16(10进制);
-4 >> 2 : 10000000 00000000 00000000 00000100(原)
→ 11111111 11111111 11111111 11111011(反)
→ 11111111 11111111 11111111 11111100(补)
→ 11111111 11111111 11111111 11111111(带符号右移2位)
→ 10000000 00000000 00000000 00000000(反)
→ 10000000 00000000 00000000 00000001(补)
→ -1(10进制)
-4 >>> 2: 10000000 00000000 00000000 00000100(原)
→ 11111111 11111111 11111111 11111011(反)
→ 11111111 11111111 11111111 11111100(补)
→ 00111111 11111111 11111111 11111111(无符号右移2位)
→ 1073741823(10进制)
2. 取模 取余
对于 整数 a ,b ;取模 或者 取余 需要如下 两步:
- 求整数商 c : c = a / b;
- 则 结果 r : r = a - (b * c);
取模 和 取余 的 差别 在于 求整数商 c 的 不同:
- 对于 取余运算,商值 向 0 方向取整;例如:a= -140,b = 8;则 c = -140/8 = -17.5,转为整数为 -17;所以 r = -140 - (-17 * 8) = -4;所以取余结果为 -4;
- 对于 取模运算,商值 向 负无穷方向取整;例如:a= -140,b = 8;则 c = -140/8 = -17.5,转为整数为 -18;所以 r = -140 - (-18 * 8) = 4;所以取模结果为 4;
所以 取模和取余 的差别 即 主要在于 是否 有 负整数,如果都为正整数,结果一致。
补充 : java 中取余 和 取模
System.out.println(-140%8); // 取余 -4
System.out.println(Math.floorMod(-140, 8)); // 取模 4
1