如何在不更改 C 中其余位的情况下在特定位置设置新的位模式?
How do I set a new bit pattern in a certain position without changing the rest of the bits in C?
假设我有以下 unsigned long val = 0xfedcba9876543210
,我想将 16 个最低有效位更改为 0xabcd
。因此,原始值将更改为 unsigned long val = 0xfedcba987654abcd
。我已经有一个可以 return 0x3210
的函数 get
,但我不确定如何将这部分值更改为 0xabcd
。有关更多上下文,这是我要实现的内容:
void set_pattern(unsigned long* val, int i, unsigned short new_pattern) {
// my attempt
unsigned short old_pattern = get(val, i); // ex: returns 0x3210 when i = 0
unsigned short* ptr = NULL;
ptr = &old_pattern;
*ptr = new_pattern;
}
当我尝试时,它似乎没有像我预期的那样设置新模式。感谢任何帮助或反馈,以帮助我更好地理解 C。
好简单的解决方法:
- 0xfedcba9876543210 & 0xfedcba9876540000
- 0xfedcba9876540000 | 0x000000000000abcd
解释 , you want to apply a bitmask 将相关位清零,然后使用按位或应用新位。
让我们用 32 位来做,你想改变至少 8 个。
应用位掩码将最少 8 位变为 0。val = val & ~0xff
。 ~0xff
是 0xffffff00
。由于0 & x = 0,所有填充的位都将保留其值,所有的0无论其原始值如何都将变为0。
0x12345678 val
AND 0xffffff00 ~0xff
= 0x12345600
既然相关位已经被屏蔽掉,变为0,我们可以用按位或来覆盖它们。 val = val | new_value
。 x | 0 = x。 new_value 的无关位是 0. x | 0 = x。他们将保留 val 的价值。 val 的相关位为 0。 0 | x = x。他们将保留 new_value 的价值。
0x12345600 val
OR 0x000000ef new_value
= 0x123456ef
如果要替换不同的位,需要将位掩码和替换值移动适当的量。
假设我们想用 ef 代替 56。每个十六进制字符为 4 位,因此我们需要将位掩码和替换值都左移 8 位。
0x12345678 val
AND 0xffff00ff ~(0xff << 8) == ~0xff00
= 0x12340078
0x12340078 val
OR 0x0000ef00 new_value << 8 == 0xef00
= 0x1234ef78
假设我有以下 unsigned long val = 0xfedcba9876543210
,我想将 16 个最低有效位更改为 0xabcd
。因此,原始值将更改为 unsigned long val = 0xfedcba987654abcd
。我已经有一个可以 return 0x3210
的函数 get
,但我不确定如何将这部分值更改为 0xabcd
。有关更多上下文,这是我要实现的内容:
void set_pattern(unsigned long* val, int i, unsigned short new_pattern) {
// my attempt
unsigned short old_pattern = get(val, i); // ex: returns 0x3210 when i = 0
unsigned short* ptr = NULL;
ptr = &old_pattern;
*ptr = new_pattern;
}
当我尝试时,它似乎没有像我预期的那样设置新模式。感谢任何帮助或反馈,以帮助我更好地理解 C。
好简单的解决方法:
- 0xfedcba9876543210 & 0xfedcba9876540000
- 0xfedcba9876540000 | 0x000000000000abcd
解释
让我们用 32 位来做,你想改变至少 8 个。
应用位掩码将最少 8 位变为 0。val = val & ~0xff
。 ~0xff
是 0xffffff00
。由于0 & x = 0,所有填充的位都将保留其值,所有的0无论其原始值如何都将变为0。
0x12345678 val
AND 0xffffff00 ~0xff
= 0x12345600
既然相关位已经被屏蔽掉,变为0,我们可以用按位或来覆盖它们。 val = val | new_value
。 x | 0 = x。 new_value 的无关位是 0. x | 0 = x。他们将保留 val 的价值。 val 的相关位为 0。 0 | x = x。他们将保留 new_value 的价值。
0x12345600 val
OR 0x000000ef new_value
= 0x123456ef
如果要替换不同的位,需要将位掩码和替换值移动适当的量。
假设我们想用 ef 代替 56。每个十六进制字符为 4 位,因此我们需要将位掩码和替换值都左移 8 位。
0x12345678 val
AND 0xffff00ff ~(0xff << 8) == ~0xff00
= 0x12340078
0x12340078 val
OR 0x0000ef00 new_value << 8 == 0xef00
= 0x1234ef78