假设我有一个像 1010XXXX 这样的字节,其中 X 值可以是任何值。我想将低四位设置为特定模式,比如 1100,而高四位不受影响。我将如何在 C 中以最快的速度做到这一点?
问问题
43932 次
4 回答
55
一般来说:
value = (value & ~mask) | (newvalue & mask);
mask
是一个所有要更改的位(并且只有它们)设置为 1 的值 - 在您的情况下它将是 0xf 。newvalue
是一个包含这些位的新状态的值 - 所有其他位基本上都被忽略了。
这适用于支持按位运算符的所有类型。
于 2010-12-14T12:36:57.520 回答
17
您可以通过按位与设置所有这些位为 0,其中 4 位设置为 0,所有其他位设置为 1(这是设置为 1 的 4 位的补码)。然后,您可以像往常一样按位或按位。
IE
val &= ~0xf; // Clear lower 4 bits. Note: ~0xf == 0xfffffff0
val |= lower4Bits & 0xf; // Worth anding with the 4 bits set to 1 to make sure no
// other bits are set.
于 2010-12-14T12:23:55.337 回答
1
使用按位运算符或 | 当您想将字节的位从 0 更改为 1 时。
当您想将字节的位从 1 更改为 0 时,请使用按位运算符和 &
例子
#include <stdio.h>
int byte;
int chb;
int main() {
// Change bit 2 of byte from 0 to 1
byte = 0b10101010;
chb = 0b00000100; //0 to 1 changer byte
printf("%d\n",byte); // display current status of byte
byte = byte | chb; // perform 0 to 1 single bit changing operation
printf("%d\n",byte);
// Change bit 2 of byte back from 1 to 0
chb = 0b11111011; //1 to 0 changer byte
byte = byte & chb; // perform 1 to 0 single bit changing operation
printf("%d\n",byte);
}
也许有更好的方法,我不知道。这将暂时帮助你。
于 2017-07-26T15:35:53.440 回答
1
为了进一步概括给出的答案,这里有几个宏(针对 32 位值;针对不同的位域长度进行调整)。
#include <stdio.h>
#include <stdint.h>
#define MASK(L,P) (~(0xffffffff << (L)) << (P))
#define GET_VAL(BF,L,P) (((BF) & MASK(L,P)) >> P)
#define SET_VAL(BF,L,P,V) ( (BF) = ((BF) & ~MASK(L,P)) | (((V) << (P)) & MASK(L,P)) )
int main(int argc, char ** argv)
{
uint32_t bf = 1024;
printf("Bitfield before : %d , 0x%08x\n", bf, bf);
printf("Mask(5,3): %d , 0x%08x\n", MASK(5,3), MASK(5,3));
SET_VAL(bf,5,3,19);
printf("Bitfield after : %d , 0x%08x\n", bf, bf);
return 0;
}
顺便说一句,C 位域完全没用是荒谬的。它是满足此要求的完美语法糖,但由于将其留给每个编译器按照它认为合适的方式实现,因此对于任何实际使用都是无用的。
于 2021-01-25T06:08:44.053 回答