我正在尝试编写一个函数,用一个新值替换大小为2 ^ x的某个“块”。
例如,如果我有一个数字1110 1000 0010
并且我想用0110
替换第2块(最大块大小为2 ^ 4),我会得到0110 1000 0010
。同样,如果我希望用110
替换块2(最大块大小为2 ^ 3),我会得到111 110 000 010
或1111 1000 0010
。
replace_block (value, x, blockNumber, newValue) {
value |= ((value >> (blockNumber*x) & ~((1 << x) – 1)) | newValue) << (blockNumber*x)
}
Step by step process of what I'm trying to do with this code:
1. Shift the block we want all the way to the right
2. Mask that block with 0's
3. Mask that block again, but with the new value we want
4. Shift the block all the way back to the original position
5. Or the bits in the block with the original value
这是我到目前为止所做的,但我不认为这是正确的。
注意:最右边的块是块0。
答案 0 :(得分:2)
首先我们需要掩码:掩码是一组“块大小”广泛移位到右侧块。
(1<<size) - 1
((1<<size)-1) << (number*size)
首先,我们清除将被替换的位置中的位,然后我们将其保留在我们想要的位中。
oldv & ~mask
newv << (number*size)
(newv<<(number*size)) & mask
(oldv&~mask) | ((newv<<(number*size))&mask)
所以你想要的代码是:
mask=(((1<<size)-1)<<(number*size));
result=((oldv&~mask)|((newv<<(number*size))&mask));
测试程序:
#include <stdio.h>
void printbits(int n) {
unsigned int i = 1<<(sizeof(n) * 8 - 1);
while (i > 0) {
if (n & i)
printf("1");
else
printf("0");
i >>= 1;
}
}
int main(void) {
int size,number,mask,oldv,newv,result;
size=4;number=2;oldv=0;newv=15;
mask=(((1<<size)-1)<<(number*size));
result=((oldv&~mask)|((newv<<(number*size))&mask));
printf("\nsize = %d\nnumber = %d",size,number);
printf("\noldv = "); printbits(oldv);
printf("\nnewv = "); printbits(newv);
printf("\nmask = "); printbits(mask);
printf("\nomask = "); printbits(oldv&~mask);
printf("\nnmask = "); printbits((newv<<(number*size))&mask);
printf("\nresult = "); printbits(result);
printf("\n");
size=4;number=2;oldv=~0;newv=0;
mask=(((1<<size)-1)<<(number*size));
result=((oldv&~mask)|((newv<<(number*size))&mask));
printf("\nsize = %d\nnumber = %d",size,number);
printf("\noldv = "); printbits(oldv);
printf("\nnewv = "); printbits(newv);
printf("\nmask = "); printbits(mask);
printf("\nomask = "); printbits(oldv&~mask);
printf("\nnmask = "); printbits((newv<<(number*size))&mask);
printf("\nresult = "); printbits(result);
printf("\n");
size=3;number=2;oldv=0;newv=7;
mask=(((1<<size)-1)<<(number*size));
result=((oldv&~mask)|((newv<<(number*size))&mask));
printf("\nsize = %d\nnumber = %d",size,number);
printf("\noldv = "); printbits(oldv);
printf("\nnewv = "); printbits(newv);
printf("\nmask = "); printbits(mask);
printf("\nomask = "); printbits(oldv&~mask);
printf("\nnmask = "); printbits((newv<<(number*size))&mask);
printf("\nresult = "); printbits(result);
printf("\n");
size=3;number=2;oldv=~0;newv=0;
mask=(((1<<size)-1)<<(number*size));
result=((oldv&~mask)|((newv<<(number*size))&mask));
printf("\nsize = %d\nnumber = %d",size,number);
printf("\noldv = "); printbits(oldv);
printf("\nnewv = "); printbits(newv);
printf("\nmask = "); printbits(mask);
printf("\nomask = "); printbits(oldv&~mask);
printf("\nnmask = "); printbits((newv<<(number*size))&mask);
printf("\nresult = "); printbits(result);
printf("\n");
size=4;number=4;oldv=0xAAAAAAAA;newv=0x15;
mask=(((1<<size)-1)<<(number*size));
result=((oldv&~mask)|((newv<<(number*size))&mask));
printf("\nsize = %d\nnumber = %d",size,number);
printf("\noldv = "); printbits(oldv);
printf("\nnewv = "); printbits(newv);
printf("\nmask = "); printbits(mask);
printf("\nomask = "); printbits(oldv&~mask);
printf("\nnmask = "); printbits((newv<<(number*size))&mask);
printf("\nresult = "); printbits(result);
printf("\n");
size=5;number=3;oldv=0xAAAAAAAA;newv=0x15;
mask=(((1<<size)-1)<<(number*size));
result=((oldv&~mask)|((newv<<(number*size))&mask));
printf("\nsize = %d\nnumber = %d",size,number);
printf("\noldv = "); printbits(oldv);
printf("\nnewv = "); printbits(newv);
printf("\nmask = "); printbits(mask);
printf("\nomask = "); printbits(oldv&~mask);
printf("\nnmask = "); printbits((newv<<(number*size))&mask);
printf("\nresult = "); printbits(result);
printf("\n");
return 0;
}
结果:
size = 4
number = 2
oldv = 00000000000000000000000000000000
newv = 00000000000000000000000000001111
mask = 00000000000000000000111100000000
omask = 00000000000000000000000000000000
nmask = 00000000000000000000111100000000
result = 00000000000000000000111100000000
size = 4
number = 2
oldv = 11111111111111111111111111111111
newv = 00000000000000000000000000000000
mask = 00000000000000000000111100000000
omask = 11111111111111111111000011111111
nmask = 00000000000000000000000000000000
result = 11111111111111111111000011111111
size = 3
number = 2
oldv = 00000000000000000000000000000000
newv = 00000000000000000000000000000111
mask = 00000000000000000000000111000000
omask = 00000000000000000000000000000000
nmask = 00000000000000000000000111000000
result = 00000000000000000000000111000000
size = 3
number = 2
oldv = 11111111111111111111111111111111
newv = 00000000000000000000000000000000
mask = 00000000000000000000000111000000
omask = 11111111111111111111111000111111
nmask = 00000000000000000000000000000000
result = 11111111111111111111111000111111
size = 4
number = 4
oldv = 10101010101010101010101010101010
newv = 00000000000000000000000000010101
mask = 00000000000011110000000000000000
omask = 10101010101000001010101010101010
nmask = 00000000000001010000000000000000
result = 10101010101001011010101010101010
size = 5
number = 3
oldv = 10101010101010101010101010101010
newv = 00000000000000000000000000010101
mask = 00000000000011111000000000000000
omask = 10101010101000000010101010101010
nmask = 00000000000010101000000000000000
result = 10101010101010101010101010101010