设置m位到n位 [英] set the m-bit to n-bit
问题描述
我有一个 32位
号,并且不使用for循环,我想设置 M
位<强>到 N
位。
I have a 32-bit
number and without using for loop, I want to set m
bit to n
bits.
例如:
M
位可能是 2号
或 5
或 9
或 10
。结果
N
位可以被 22
或 27
或 11
位。
m
bit may be 2nd
or 5th
or 9th
or 10th
.
n
bit may be 22nd
or 27
or 11th
bit.
我假设(M&LT; N)。
I assume (m < n).
请帮忙me.Thanks
Please help me.Thanks
推荐答案
尽管这个问题已经被关闭,但我不知道我的老答案。我曾与测试code更新。希望这将是有人在将来有所帮助。
Although the question has been closed, but as I was not sure for my old answer. I have updated with tested code. Hope it would be helpful for someone in future.
假设位编号为LSB到MSB:
Suppose Bits are numbered from LSB to MSB:
BIT NUMBER 31 0
▼ ▼
number bits 0000 0000 0000 0000 0000 0000 0001 0101
▲ ^ ^ ▲
MSB | | LSM
| |
n=27 m=17
LSB - Least Significant Bit (numbered 0)
MSB - Most Significant Bit (numbered 31)
在上面的身影,我已经表明位如何从LSB到MSB编号。
注意 N
和 M
,其中 N'GT的相对位置;米
。
要设定的 1
从位置所有位的 M
为 N
(其中 N'GT,M
)的一个32位数字。
你需要一个32位掩码的所有比特都是 1
从 N
到<$ C $ç> M 和剩余
位的 0
To set-1
all bits from position m
to n
(where n > m
) in a 32-bit number.
You need a 32 bit mask in which all bits are 1
from n
to m
and remaining
bits are 0
.
例如设置所有位的 M = 17
为 N = 27
我们需要像面膜:
For example to set all bits from m=17
to n=27
we need mask like:
BIT NUMBER 31 n=27 m=17 0
▼ ▼ ▼ ▼
mask = 0000 1111 1111 1110 0000 0000 0000 0000
如果我们有任何32位的号码,通过按位OR( |
)这个数字,我们可以设定的 1
从 M
所有的位 N
。和其他位将保持不变。
And if we have any 32-bits number, by bitwise OR (|
) with this number we can set-1
all bits from m
to n
. And other bits will be unchanged.
记住或工作方式类似:
x | 1 = 1 , and
x | 0 = x
其中, X
value可以是 1
或 0
任何。
where x
value can be 1
or 0
any.
因此,通过这样做的:
So by doing:
num32bit = num32bit | mask;
我们可以设置 N
到 M
位 1
而剩下的位将保持不变。一个例子,
假设, num32bit
= 0011 1001 1000 0000 0111 1001 0010 1101
we can set n
to m
bit 1
and remaining bits will be unchanged. An example,
Suppose, 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
"This is what I means by":
num32bit = num32bit | mask;
如何使面膜?
为了让面膜中的所有比特都是 1
从 N
到 M
等都是 0
。
我们需要三个步骤:
To make mask in which all bits are 1
from n
to m
and other are 0
.
we need Three steps:
-
创建mask_n
:从在右侧所有位N = 27
是一体
BIT NUMBER 31 n=27 0
▼ ▼ ▼
mask_27= 0000 1111 1111 1111 1111 1111 1111 1111
在这个程序可以通过右移创建>> 4倍。
In programming this can be create by Right-Shift >> 4 times.
和 4
如何来的?
And, How 4
came?
4 = 32 - n - 1 ==> 31 - 27 ==> 4
此外,在补充说明(〜
)的形式 0
的所有位是一体的。
我们需要<一个href=\"http://stackoverflow.com/questions/2429479/how-do-i-perform-an-unsigned-right-shift-in-java-in-c-c\">unsigned权C.转移结果
链接了解与<差异href=\"http://stackoverflow.com/questions/15457893/java-right-shift-on-negative-number/15457908#15457908\">signed和无符号右移
Also note in complement (~
) form of 0
all bits are one.
and we need unsigned right shift in C.
Link to learn difference between signed and unsigned right shift
创建mask_m
:从左侧的所有位 M = 17
是一体的。
BIT NUMBER 31 m=17 0
▼ ▼ ▼
mask_17 1111 1111 1111 1110 0000 0000 0000 0000
创建面具
:按位与以上为: =面膜&mask_n放大器; mask_m
:
mask = 0000 1111 1111 1110 0000 0000 0000 0000
▲ ▲
BIT NUMBER 27 17
和,下面是返回一个无符号数,看起来像在步骤3面膜我的 getMask(N,M)
功能。
And, below is my getMask(n, m)
function that returns a unsigned number that looks like mask in step-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()$ C $使用二进制()函数c,二进制()函数打印二进制甲酸给定数。
To test my getMask() I also written main() code that uses a binary() function, binary() function prints a given number in binary formate.
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");
}
此测试code运行像(输出完全相同,因为我在上面的例子解释):
This test code runs like( the output is quite same as I explained in above example):
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()函数在较短的形式在两个语句,如下所示:
Additional, You can write getMask() function in shorter form in two statements, as follows:
unsigned getMask(unsigned n,
unsigned m){
byte noOfBits = sizeof(unsigned) * BYTE;
return ((unsigned)~0u >> (noOfBits - n - 1)) &
(~0u << (noOfBits -m));
}
注意:我删除多余的括号,清理的code。虽然你从来不需要想起运营商precedence,你可以使用覆盖precedence ()
。但是,一个好的程序员总是裁判precedence表写工整code。
Notice: I removed redundant parenthesis, to cleanup the code. Although you never need to remember precedence of operators as you can overwrite precedence using ()
. But a good programmer always referees to precedence table to write neat code.
和更好的方法可能是写微距(),如下:
And Better approach may be to write Macro() as below:
#define BYTE 8
#define _NO_OF_BITS sizeof(unsigned) * BYTE
#define MASK(n, m) (((unsigned)~0u >> (_NO_OF_BITS - n - 1)) & \
(~0u << (_NO_OF_BITS - m)))
和调用,如:
rsult32bit = num32bit | MASK(27, 17);
从n的所有零位设置为M
要设置所有位从n到m = 0,并且复位是不变的,你只需要补(〜 )
面膜
。
mask 0000 1111 1111 1111 1000 0000 0000 0000
~mask 1111 0000 0000 0000 0111 1111 1111 1111 <-- complement
此外,而不是 |
操作员设置为零&安培;
是必需的。
Also instead of |
operator to set zero &
is required.
记住和的工作原理是:
x & 0 = 0 , and
x & 0 = 0
其中, X
值可以是1或0的。
由于我们已经有了一个位元补码〜
运营商,和&安培;
运营商。我们只是需要做的。结果
[解决]
Because we already have a bitwise complement ~
operator and and &
operator. We just need to do.
[SOLUTION]:
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
这篇关于设置m位到n位的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!