初步认识java中的移位运算符

来源:力扣(LeetCode)
链接:面试题 05.01. 插入

有关移位运算符

左移运算符:<<

不区分正负数,左移之后在右边补0, 相当于num乘以2

public class test {

	public static void main(String[] args) {
		int A = 8;
		System.out.println("A : " + Integer.toBinaryString(A));
		int M, N;
		M = A << 1;
		System.out.println("M : " + M);//相当于乘以2
		System.out.println(Integer.toBinaryString(M));
		
		N = A << 2;
		System.out.println("N : " + N);//相当于乘以4
		System.out.println(Integer.toBinaryString(N));
	}
}
A : 1000
M : 16
10000
N : 32
100000

右移运算符:>>

右移之后在左边补上符号位,正数补0,负数补1,相当于num除以2

无符号右移:>>>

无论该数为正还是为负,右移之后左边补0

>>>>> 对比:

public class test {

	public static void main(String[] args) {
		int A = -5;
		System.out.println(Integer.toBinaryString(A));
		
		System.out.println(Integer.toBinaryString(A >> 1));
		System.out.println(Integer.toBinaryString(A >>> 1));
		
		System.out.println(Integer.toBinaryString(A >> 2));
		System.out.println(Integer.toBinaryString(A >>> 2));
	}
}

11111111111111111111111111111011//A
11111111111111111111111111111101//A>>1,负数:在左边补符号位1
1111111111111111111111111111101//A>>>1
11111111111111111111111111111110//A>>2,负数:在左边补符号位1
111111111111111111111111111110// A>>>2

题目

给定两个32位的整数N与M,以及表示比特位置的i与j。编写一种方法,将M插入N,使得M从N的第j位开始,到第i位结束。假定从j位到i位足以容纳M,也即若M = 10 011,那么j和i之间至少可容纳5个位。例如,不可能出现j = 3和i = 2的情况,因为第3位和第2位之间放不下M。

输入:N = 10000000000, M = 10011, i = 2, j = 6
输出:N = 10001001100

输入: N = 0, M = 11111, i = 0, j = 4
输出:N = 11111

题目解析

题目大意是将 N 的 i 到 j 位用 M 代替(注意这里的 i 与 j 是从二进制的末尾开始的,并且是从 0 开始的),也就是说将 M 分成了三个数:0 — i-1(其余位为0), i — j(其余位为0), j+1 —最高位(其余位为0),这三个数字或运算的结果,就是最终答案。

  • 0 — i-1(其余位为0):通过将 1 << i,然后减 1,最后和N进行与运算

例如 i = 2,
1 << i = 100(其余位为0)
(1 << i) - 1 = 11(其余位为0)
N & (1 << i) - 1 得到最后 i 由有 N 的前 0 — i - 1 位决定,其余位为0

  • i — j(其余位为0): M << i 即可(其余位补0)
  • j+1 —最高位(其余位为0):N >> j >> 1 << j << 1,即 N 右移 j + 1 位后再左移 j + 1 为,则 j + 1 —最高位保持不变,其余位为0(注意:java里面32位整数n左移32位的结果是n循环左移而不是置零,当j=31,会导致循环左移,则代码 1<<j+1应改为 1<<j<<1)

代码

class Solution {
    public int insertBits(int N, int M, int i, int j) {
        int left = N & (1 << i) - 1;
        int right = N >> j >> 1 << j << 1;
        int mid = M << i;
        return left | mid | right;//( | 的顺序不影响结果)
    }
}

示例

public class L0501 {

	public static void main(String[] args) {
		int N = 67, M = 15, i = 2, j = 5;
		System.out.println(Integer.toBinaryString(N));
		System.out.println(Integer.toBinaryString(M));
		
		int l = N&(1<<i)-1;
        int h = N>>j>>1<<j<<1;
        int m = M<<i;
        
		System.out.println(Integer.toBinaryString(l));
		System.out.println(Integer.toBinaryString(h));
		System.out.println(Integer.toBinaryString(m));
		System.out.println(Integer.toBinaryString(l|h|m));
	}

}

结果

1000011
1111
11
1000000
111100
1111111
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值