一种直接根据掩码转位的方法
A direct way to turn bits according to mask
假设我们有一个字节 B
和一个掩码 M
使得掩码中的一位为 1 或 0 而其他位为 0,(假设我们知道哪一位是是,它可以是任何位,但为简单起见,它是 LSB)。我们希望 B
中的相同位与 M
中的相同位具有相同的值。
例如如果B=1111
,M=0000
那么我们希望运算后有B=1110
,但是如果M
是M=0001
那么B
本来是 B=1111
.
我基本上是在问如何实现根据这个真理生成的布尔函数table:
old new result
0 0 0
0 1 1
1 0 0
1 1 1
所以 result
将是:
a=old, b= new
result=a'b+ab
在 C 中执行 B = ~B&M | B&M;
似乎不起作用...
我可能可以使用条件语句来做到这一点,但是没有它们就必须有一种方法。
另一个例子:
如果我们关心第二位,如果B=0001
,M=0010
那么操作的结果将是0011
。但是如果 M
是 M=0000
那么操作的结果是 0001
.
我知道如何设置清除和切换位,这不是我要问的。
它不能作为布尔函数实现,因为您要使用的运算符是按位的,因此操作数是多位的。但是您可以合并一些移位来适应这一点:
#define BIT_NUMBER 3 // For example
B &= ~(1 << BIT_NUMBER); // Zero out the bit
B |= M << BIT_NUMBER; // Set to M's bit value
您需要指定您关心的位的偏移量(例如index
):
char AssignBit(unsigned char byte, unsigned char mask, int index)
{
unsigned char cleared = byte & ~(1 << index);
unsigned char assigned = cleared | mask & (1 << index);
return assigned;
// or simply:
return byte & ~(1 << index) | mask & (1 << index);
// if it is guaranteed that at most one bit is set in mask, this also works:
return byte & ~(1 << index) | mask;
}
如何将第 n
位更改为 x
:
number ^= (-x ^ number) & (1 << n);
(摘自)
For example if B=1111, M=0000 then we want to have after the operation
B=1110
问题是你没有指定M
中的哪个位是有效的,并且无法从M
的值中确定有效位。
您实际上需要三个数量,字节 B
、值 V
(您称之为 M)和掩码 M
(您的问题中缺少).
下面是结合了这三者的代码:
result = (B & ~M) | (V & M);
如果我没理解错的话,您想将 B 中的单个位设置为 M 中该位的值,而您不关心 B 中的先前值是什么。在这种情况下,M 并不是真正的面具;您的掩码由位数给出。所以你会做类似
的事情
unsigned mask = (1<<BITNUM);
unsigned result = (~mask & B) | (mask & M)
如果是 LSB,则 BITNUM = 0。
假设我们有一个字节 B
和一个掩码 M
使得掩码中的一位为 1 或 0 而其他位为 0,(假设我们知道哪一位是是,它可以是任何位,但为简单起见,它是 LSB)。我们希望 B
中的相同位与 M
中的相同位具有相同的值。
例如如果B=1111
,M=0000
那么我们希望运算后有B=1110
,但是如果M
是M=0001
那么B
本来是 B=1111
.
我基本上是在问如何实现根据这个真理生成的布尔函数table:
old new result
0 0 0
0 1 1
1 0 0
1 1 1
所以 result
将是:
a=old, b= new
result=a'b+ab
在 C 中执行 B = ~B&M | B&M;
似乎不起作用...
我可能可以使用条件语句来做到这一点,但是没有它们就必须有一种方法。
另一个例子:
如果我们关心第二位,如果B=0001
,M=0010
那么操作的结果将是0011
。但是如果 M
是 M=0000
那么操作的结果是 0001
.
我知道如何设置清除和切换位,这不是我要问的。
它不能作为布尔函数实现,因为您要使用的运算符是按位的,因此操作数是多位的。但是您可以合并一些移位来适应这一点:
#define BIT_NUMBER 3 // For example
B &= ~(1 << BIT_NUMBER); // Zero out the bit
B |= M << BIT_NUMBER; // Set to M's bit value
您需要指定您关心的位的偏移量(例如index
):
char AssignBit(unsigned char byte, unsigned char mask, int index)
{
unsigned char cleared = byte & ~(1 << index);
unsigned char assigned = cleared | mask & (1 << index);
return assigned;
// or simply:
return byte & ~(1 << index) | mask & (1 << index);
// if it is guaranteed that at most one bit is set in mask, this also works:
return byte & ~(1 << index) | mask;
}
如何将第 n
位更改为 x
:
number ^= (-x ^ number) & (1 << n);
(摘自)
For example if B=1111, M=0000 then we want to have after the operation B=1110
问题是你没有指定M
中的哪个位是有效的,并且无法从M
的值中确定有效位。
您实际上需要三个数量,字节 B
、值 V
(您称之为 M)和掩码 M
(您的问题中缺少).
下面是结合了这三者的代码:
result = (B & ~M) | (V & M);
如果我没理解错的话,您想将 B 中的单个位设置为 M 中该位的值,而您不关心 B 中的先前值是什么。在这种情况下,M 并不是真正的面具;您的掩码由位数给出。所以你会做类似
的事情unsigned mask = (1<<BITNUM);
unsigned result = (~mask & B) | (mask & M)
如果是 LSB,则 BITNUM = 0。