位运算符(难点、非重点)

位运算符(难点、非重点)

1. 基本语法
运算符运算范例
<<左移3 << 2 = 12 --> 3 * 2 * 2 = 12
>>右移3 >> 1 = 1 --> 3 / 2 = 1
>>>无符号右移3 >>> 1 = 1 --> 3 / 2 = 1
&与运算6 & 3 = 2
|或运算6 | 3 = 7
^异或运算6 ^ 3 = 5
~取反运算~6 = -7 或者 ~-7 = 6
/**
测试运算符的使用5:位运算符

1. <<  >>  >>>  &  |   ^   ~
2. 说明:
① <<  >>   >>>  &  |   ^   ~: 针对数值类型的变量或常量进行运算,运算的结果也是数值
② << : 每向左移动一位,结果就在原有的基础上 *  2(对于正数、负数都适用)
>> : 每向右移动一位,结果就在原有的基础上 / 2(对于正数、负数都适用)

3. 面试题:高效的方式计算 2 * 8?
   2  <<  3 相当于 2 *  2 ^ 3 
   或者 8 << 1(8 左移 1位) 
   
*/
class BitTest{
   public static void main(String[] args){
       int num1 = 7;
       
       System.out.println("num1左移一位时,结果是: " + (num1 << 1));
       // 输出结果是14  7 * 2 ^ 1  = 14
       System.out.println("num1左移二位时,结果是: " + (num1 << 2));
       // 输出结果是28   7 * 2 ^ 2 = 28
       System.out.println("num1左移三位时,结果是: " + (num1 << 3));
       // 输出结果是56   7 * 2 ^ 3 = 56

       int num2 = -7;
       
       System.out.println("num2左移一位时,结果是: " + (num2 << 1));
       // 输出结果是-14  -7 * 2 ^ 1  = -14
       System.out.println("num2左移二位时,结果是: " + (num2 << 2));
       // 输出结果是-28   -7 * 2 ^ 2 = -28
       System.out.println("num2左移三位时,结果是: " + (num2 << 3));
       // 输出结果是-56   -7 * 2 ^ 3 = -56
   }
}

注意:

  1. 当左移的位数n超过该数据类型的总位数时,相当于左移(n - 总位数)位
    • 这句话的意思是:当对一个数据类型执行左移操作时,如果左移的位数n超过了该数据类型的总位数,那么实际上等价于将左移的位数减去该数据类型的总位数(n-总位数)后再进行左移。换言之,只有左移的位数小于总位数才是有效的左移,超过总位数时需要对位数进行调整。

举例:

  • 3 << 4 相当于 3 * 2 的4次幂 => 3 * 16 = 48
  • -3 << 4 相当于 -3 * 2 的四次幂 => -3 * 16 = -48
  1. 右移时如果不能整除,向下取整。正数补0,负数补1。
  2. 无符号右移:>>>
    运算规则:往右移动后,左边空出来的位直接补0。(正数、负数都适用)
  • 举例: 69 >>> 4 类似于 69 / 2 的 4次 = 69 /16 = 4
  • -69 >>> 4 结果: 268435451
/*
-69的二进制:
    补码: 1000 0000 0000 0000 0000 0000 0100 0101 
    反码: 1111 1111 1111 1111 1111 1111 1011 1010
    补码: 1111 1111 1111 1111 1111 1111
1011 1011

-69 >>> 4: 0000 1111 1111 1111 1111 1111 
1111 1011
 最高位是0,是正数,那么原码,反码,补码都一样
 计算用补码,看结果用原码
 一般情况下。乘以二用<<,除以二用>>。
 那什么情况下用无符号右移>>>?
 一般情况下,使用无符号右移 ">>>" 操作符可以对某些无符号整型数据进行操作。例如:IPv4地址的存储就是采用无符号整型数据类型的方式来表示。在对这种类型的数据进行操作时,经常需要用到无符号右移 ">>>" 操作符。

另外,在对一些大数据量进行移位运算时,使用无符号右移操作符 ">>>" 可能会比有符号右移操作符 ">>" 效率更高,因为它不需要考虑符号位的处理,执行效率可能更高。
*/

案例:如何交换两个int型变量的值?String呢?

class BitExer{
   public static void main(String[] args){
       int m = 10;
       int n = 20;
       System.out.println("m ="+ m + ",n = " + n);
       // 交换两个变量的值
       // 方法1:声明一个临时变量(推荐)
       
       int temp = m;
              m = n;
              n = temp;
       System.out.println("m = " + m + ", n =  " + n);
       
       // 方法2:使用加减法
       // 优点:不需要定义临时变量。
       // 缺点:难、适用性差(不适用于非数值类型)、可能超出int的范围
       
       int a = 1 ;
       int b = 2;
       a = a + b; // a = 3
       b = a - b; // b = 1
       a = a - b; // a = 2

       // 方法3:使用位运算
       // 优点: 不需要定义临时变量
       // 缺点: 真难、适用性差(不适用于非数值类型)
       // m = k ^ n = (m ^ n) ^ n
       int  a = 1;
       int  b = 2;
       a = a ^ b;
       b = a ^ b; // (m ^ n) ^ n ---> m
       a = a ^ b;

       // 方法4: 使用数组
       int[] arr = new int[]{1,2};
       arr[0] = arr[0] + arr[1];
       arr[1] = arr[0] - arr[1];
       arr[0] = arr[0] - arr[1];
       int a = arr[0];
       int b = arr[1];
       
       // 注意:以上的方法都可以用于基本数据类型,但对于引用数据类型,如类、对象等,需要考虑引用的指向问题。
       // 此外,第 3 种方法使用了异或操作符,不适用于浮点数和其他非整型数据类型
       // 主要推荐第一种方式:声明一个临时变量
   }                          
}
笔记来源:

尚硅谷Java零基础全套视频教程第三十八集

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值