给出两个32位的整数N和M,以及两个二进制位的位置i和j。写一个方法来使得N中的第i到j位等于M(M会是N中从第i为开始到第j位的子串)

610 阅读2分钟

分析

参考链接:zhuanlan.zhihu.com/p/26890617

思路

根据题意,可以有一个想法,将n中第i位到第j位的先置为0,然后,按位或m << i即可。

Basic

负数的二进制表示

在计算机中,负数的二进制以其正数的补码形式来表示。

原码:一个正数的二进制表示(包括负数的绝对值)
反码:所有位取反
补码:反码 + 1

示例:表示-5的二进制
5的二进制数:101,补零为 00000101
原码:00000101
反码:11111010
补码:11111011

11111011即表示8位的 -5。
如果要表示16位的-5,左边添上8个1即可,即 11111111 11111011

问题分解

现在问题是如何将n中第i位到第j位置为0,可以考虑构造一个数,这个数从第i位到第j位是0,其他位都为1。

这样的数并不是很好构造,所以,我们构造一个数从第i位到第j位都是1,其他位为0的数,然后将这个数取反,就可以得到从第i位到第j位是0,其他位是1的数。

-1的二进制表示是所有位为1,我们以这个数为起点。需要的做的是将高(31-j)位置0,将低i位置0。

将-1先左移(31-j)位,因为高(31-j)位都是不需要的。

然后再将((-1) << (31 - j))逻辑右移(31 - j + i)位,因为要将低i位置0.

然后再将(((-1) <<(31 - j)) >>> (31 - j + i))左移i位,将1恢复到正确的位置即可。即得到第i位到第j位是1,其他位是0的数。