bitmanipulation(1)

You are given two 32-bit numbers, N and M, and two bit positions, i and j. Write a method to set all bits between i and j in N equal to M (e.g., M becomes a substring of N located at i and starting at j).
EXAMPLE:
Input: N = 10000000000, M = 10101, i = 2, j = 6
Output: N = 10001010100

solution中是有错误的

假设n的j位为1,m左边第一位为0,那么结果将会出错。

因为按该方法算mask的时候第j位的值是1而不是0。但是本来第j位是应该设置成0的,所以就会出错。

可以用n=10010100000,m=000101,i=2,j=7,这个case去验证solution的错误

目标分两部:第一步把n的i位到j位之间的位数全置为0,第二步把
n的i位到j位之间的数赋成m
 
 
为实现第一步把n的i位到j位之间的位数全置为0的目标,需要把n与某个数设为mask进行and操作,因为其他操作无法保证i到j位全为0
and操作的话只需让mask数组i位到j位为0,其余位为1即可。

设左边的位数算作该位之前的,右边的位数算该位之后的
leftj位之前(不含j位)都是1,j位之后(含j位)都是0
 
right变量i位之后(不含i位)都是1 其余0
 
 
mask=left|right
mask数组
 
mask这个数的i位于j位之间都是0
其余均为1
 
return (n & mask) | (m << i);
 
 
n&mask把n的i位到j位之间的全置为0
其他位上保持不变
 
然后与m左移i结果进行或操作
#include<iostream>
#include<bitset>
using namespace std;

void updateBits(string s,string t,int i,int j){
    bitset<32> n(s);  
    bitset<32> m(t);  
    int max= ~0;
    //我感觉这里应该1左移j+1位,这样((1 << (j+1)) - 1)操作
    //j位之后包括j位都是1
    //然后left中j位之后含j位都是0,left其余位为1
    bitset<32> left = max - ((1 << (j+1)) - 1);
    bitset<32> right = (1 << i) - 1;
    bitset<32> mask = left | right;
    //cout<<"mask"<<mask<<endl;
    //cout<<"mask1:"<<(n & mask)<<endl;
    cout<<((n & mask) |(m << i));
}


int main(){
    string s="10010100000";
    string t="000101";
    updateBits(s,t,2,7);
    system("pause");

}
原文地址:https://www.cnblogs.com/richardcpp/p/3055419.html