设置m位到n位 [英] set the m-bit to n-bit

查看:152
本文介绍了设置m位到n位的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 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:


  1. 创建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屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆