gpt4 book ai didi

c - 将 m 位设置为 n 位

转载 作者:行者123 更新时间:2023-11-30 18:17:40 26 4
gpt4 key购买 nike

我有一个32-bit数字并且不使用 for 循环,我想设置 m n位。

例如:

m位可能是2nd5th9th10th .
n位可能是22nd2711th少量。

我假设 (m < n)。

请帮助我。谢谢

最佳答案

假设位从 LSB 到 MSB 编号:

BIT NUMBER    31                                     0
▼ ▼
number bits 0000 0000 0000 0000 0000 0000 0001 0101
▲ ^ ^ ▲
MSB | | LSB
| |
n=27 m=17

LSB - Least Significant Bit (numbered 0)
MSB - Most Significant Bit (numbered 31)

在上图中,我展示了如何从 LSB 到 MSB 对位进行编号。注意 n 的相对位置和m哪里n > m .

<小时/>

设置从 n 到 m 的(全 1)位

<小时/>

设置- 1 位置 m 的所有位 n (其中 n > m )为 32 位数字。您需要一个 32 位掩码,其中所有位均为 1 来自 nm其余位为 0

例如,设置 m=17 中的所有位 n=27 我们需要这样的面具:

BIT NUMBER    31   n=27        m=17                  0
▼ ▼ ▼ ▼
mask = 0000 1111 1111 1110 0000 0000 0000 0000

如果我们有任何 32 位数字,通过按位或 ( | ) 与该数字我们可以设置 - 1 来自 m 的所有位至n 。所有其他位将保持不变。

记住 OR 的工作原理如下:

x | 1 = 1   , and 
x | 0 = x

哪里x值可以是 10 .

所以通过这样做:

 num32bit = num32bit | mask; 

我们可以设置nm1其余位将保持不变。例如,假设 num32bit =0011 1001 1000 0000 0111 1001 0010 1101 ,

然后:

0011 1001 1000 0000 0111 1001 0010 1101   <--- num32bit
0000 1111 1111 1110 0000 0000 0000 0000 <--- mask
---------------------------------------- ---------------Bitwise OR operation
0011 1111 1111 1110 0111 1001 0010 1101 <--- new number
---- ▲ ▲ -------------------
|-----------| this bits are from `num32bit`
all bits are
1 here

这就是我的意思:

     num32bit = num32bit | mask; 

##如何制作面具?

制作一个掩码,其中所有位都是 1来自nm其他的是 0 ,我们需要三个步骤:

  1. Create mask_n :右侧的所有位来自 n=27是一个

     BIT NUMBER     31  n=27                              0
    ▼ ▼ ▼
    mask_27= 0000 1111 1111 1111 1111 1111 1111 1111

    在编程中,可以通过右移 ( >> ) 4 次来创建。

    而且,为什么 4

     4 = 32 - n - 1  ==> 31 - 27 ==> 4

    另请注意:~ 的补码 ( 0 )所有位均为 1,我们需要unsigned right shift在C中
    了解difference between signed and unsigned right shift

  2. Create mask_m :左侧的所有位来自 m=17是其中之一。

     BIT NUMBER    31              m=17                  0
    ▼ ▼ ▼
    mask_17 1111 1111 1111 1110 0000 0000 0000 0000
  3. Create mask :上面的按位与为:mask = mask_n & mask_m :

     mask =         0000 1111 1111 1110 0000 0000 0000 0000
    ▲ ▲
    BIT NUMBER 27 17

下面是我的 getMask(n, m)函数返回一个无符号数字,类似于步骤 3 中的掩码。

#define BYTE 8
typedef char byte; // Bit_sizeof(char) == BYTE
unsigned getMask(unsigned n,
unsigned m){
byte noOfBits = sizeof(unsigned) * BYTE;
unsigned mask_n = ((unsigned)~0u) >> (noOfBits - n - 1),
mask_m = (~0u) << (noOfBits - m),
mask = mask_n & mask_m; // bitwise & of 2 sub masks
return mask;
}

测试我的getMask()我还写过main()函数和一个 binary() 函数,该函数以二进制格式打印给定的数字。

void binary(unsigned);
int main(){
unsigned num32bit = 964720941u;
unsigned mask = 0u;
unsigned rsult32bit;
int i = 51;
mask = getMask(27, 17);
rsult32bit = num32bit | mask; //set n to m bits 1
printf("\nSize of int is = %ld bits, and "
"Size of unsigned = %ld e.g.\n", sizeof(int) * BYTE,
sizeof(unsigned) * BYTE);
printf("dec= %-4u, bin= ", 21);
binary(21);
printf("\n\n%s %d\n\t ", "num32bit =", num32bit);
binary(num32bit);
printf("mask\t ");
binary(mask);
while(i--) printf("-");
printf("\n\t ");
binary(rsult32bit);
printf("\n");
return EXIT_SUCCESS;
}
void binary(unsigned dec){
int i = 0,
left = sizeof(unsigned) * BYTE - 1;
for(i = 0; left >= 0; left--, i++){
printf("%d", !!(dec & ( 1 << left )));
if(!((i + 1) % 4)) printf(" ");
}
printf("\n");
}

此测试代码的运行方式如下(输出与我在上面的示例中解释的完全相同):

Output of code: 
-----------------
$ gcc b.c
:~$ ./a.out

Size of int is = 32 bits, and Size of unsigned = 32 e.g.
dec= 21 , bin= 0000 0000 0000 0000 0000 0000 0001 0101

num32bit = 964720941
0011 1001 1000 0000 0111 1001 0010 1101
mask 0000 1111 1111 1110 0000 0000 0000 0000
---------------------------------------------------
0011 1111 1111 1110 0111 1001 0010 1101
:~$

此外,您可以写 getMask()函数以较短的形式包含在两个语句中,如下所示:

unsigned getMask(unsigned n,
unsigned m){
byte noOfBits = sizeof(unsigned) * BYTE;
return ((unsigned)~0u >> (noOfBits - n - 1)) &
(~0u << (noOfBits -m));
}

注意:我删除了多余的括号,以清理代码。尽管您永远不需要记住运算符的优先级,因为您可以使用 () 覆盖优先级。 ,一个好的程序员总是引用优先级表来编写整洁的代码。

更好的方法可能是编写如下宏:

#define _NO_OF_BITS sizeof(unsigned) * CHAR_BIT
#define MASK(n, m) (((unsigned)~0u >> (_NO_OF_BITS - n - 1)) & \
(~0u << (_NO_OF_BITS - m)))

并调用如下:

result32bit  = num32bit | MASK(27, 17);
<小时/>

将(全零)位从 n 重置为 m

<小时/>

要将所有位从 n 重置为 m = 0,并保持其余位不变,只需对 ~ 求补 ( mask ) .

mask      0000 1111 1111 1111 1000 0000 0000 0000 
~mask 1111 0000 0000 0000 0111 1111 1111 1111 <-- complement

也可以代替|运算符设置零 &是必需的。

记住AND的工作方式如下:

x & 0 = 0   , and 
x & 0 = 0

哪里x值可以是 1 或 0。

因为我们已经有了按位补 ~运算符 and 和 &运算符,我们只需要做:

rsult32bit  = num32bit & ~MASK(27, 17);

它的工作原理如下:

num32bit = 964720941
0011 1001 1000 0000 0111 1001 0010 1101
mask 1111 0000 0000 0000 0111 1111 1111 1111
---------------------------------------------------
0011 0000 0000 0000 0111 1001 0010 1101

关于c - 将 m 位设置为 n 位,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15917454/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com