[英]How do I set a new bit pattern in a certain position without changing the rest of the bits in C?
Suppose I have the following unsigned long val = 0xfedcba9876543210
and I want to change the 16 least significant bits to 0xabcd
.假设我有以下
unsigned long val = 0xfedcba9876543210
并且我想将 16 个最低有效位更改为0xabcd
。 So, the original value will be changed to unsigned long val = 0xfedcba987654abcd
.因此,原始值将更改为
unsigned long val = 0xfedcba987654abcd
。 I already have a function get
that can return 0x3210
, but I'm unsure how I can change this section of the value to 0xabcd
.我已经有一个 function
get
返回0x3210
,但我不确定如何将这部分值更改为0xabcd
。 For more context, here is what I am trying to implement:有关更多上下文,这是我要实现的内容:
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;
}
When I tried my attempt, it seemed to not set the new pattern as I expected.当我尝试我的尝试时,它似乎没有像我预期的那样设置新模式。 Any help or feedback is appreciated in helping me gain a better understanding of C.
感谢任何帮助或反馈,以帮助我更好地了解 C。
To explain Nate's comment , you want to apply a bitmask to zero out the relevant bits, then apply the new bits with a bitwise or.为了解释Nate 的评论,您想应用位掩码将相关位清零,然后使用按位或应用新位。
Let's do it with 32 bits and you want to change the the least 8.让我们用 32 位来做,你想改变最少的 8 位。
Apply a bitmask to turn the least 8 bits to 0. val = val & ~0xff
.应用位掩码将至少 8 位变为 0。
val = val & ~0xff
。 ~0xff
is 0xffffff00
. ~0xff
是0xffffff00
。 Since 0 & x = 0 , all the filled in bits will retain their value, and all the 0's will become 0 no matter their original value.由于0 & x = 0 ,所有填充的位将保留其值,并且所有 0 将变为 0,无论其原始值如何。
0x12345678 val
AND 0xffffff00 ~0xff
= 0x12345600
Now that the relevant bits have been masked out, turned to 0, we can overwrite just them with a bitwise or.现在相关位已被屏蔽,变为 0,我们可以用按位或仅覆盖它们。
val = val | new_value
val = val | new_value
. val = val | new_value
。 x | x | 0 = x .
0 = x 。 The irrelevant bits of new_value are 0. x |
new_value 的无关位为 0。 0 = x.
0 = x。 They will retain val's value.
他们将保留 val 的价值。 The relevant bits of val are 0. 0 |
val 的相关位为 0。 0 | x = x.
x = x。 They will retain new_value's value.
他们将保留 new_value 的值。
0x12345600 val
OR 0x000000ef new_value
= 0x123456ef
If you want to replace different bits, you need to shift the bitmask and replacement value the appropriate amount.如果要替换不同的位,则需要将位掩码和替换值移动适当的量。
Let's say we want to replace 56 with ef instead.假设我们想用 ef 替换 56。 Each hex character is 4 bits, so we need to left shift both the bitmask and replacement value by 8 bits.
每个十六进制字符为 4 位,因此我们需要将位掩码和替换值都左移 8 位。
0x12345678 val
AND 0xffff00ff ~(0xff << 8) == ~0xff00
= 0x12340078
0x12340078 val
OR 0x0000ef00 new_value << 8 == 0xef00
= 0x1234ef78
Well simple solution to it:很简单的解决方案:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.