设置int的前10位

时间:2015-10-04 20:26:29

标签: c bit-manipulation bit

我有一个32位的int,我想将前10位设置为特定的数字。

IE

32位int是:

11101010101010110101100100010010

我希望前10位是数字123,即

0001111011

所以结果将是

00011110111010110101100100010010

有谁知道我能做到这一点的最简单方法?我知道我们必须进行位移,但我并不擅长,所以我不确定

谢谢!

5 个答案:

答案 0 :(得分:2)

uint32_t result = (input & 0x3fffff) | (newval << 22);

0x3fffff屏蔽最高10位(设置最低22位)。您必须将最高10位的新值移动22位。

答案 1 :(得分:1)

  1. 将输入转换为无符号32位整数

    uint32_t num = strtoul("11101010101010110101100100010010", 0, 2);
    uint32_t firstbits = 123;
    
  2. 屏蔽低32-10位。通过将unsigned long 1 22个位置左移100_0000_0000_0000_0000_0000然后递减到11_1111_1111_1111_1111_1111来创建遮罩

    uint32_t mask = (1UL << (32-10)) - 1;
    num &= mask;
    
  3. firstbits左移32-10

    num |= firstbits << (32-10);
    
  4. 或者在一行中:

    (num & (1UL << (32-10)) - 1) | (firstbits*1UL << (32-10))
    
  5. 关于firstbits*1UL的详细信息。 firstbits的类型不是由OP定义的,可能只是16位int。为确保代码可以移位并形成超过16位(int的最小宽度)的答案,多次1UL以确保该值为无符号且至少具有32位宽度。

答案 2 :(得分:0)

你可以&#34;擦除&#34;比特(将它们设置为0)通过使用位和(&#39;&amp;&#39;);在任一值中为0的位在结果中将为0。

您可以使用位或(&#39; |&#39;)将位设置为1;在任一值中为1的位在结果中将为1。

所以:你的数字的前10位为0,其余为1;然后&#39;或&#39;它需要输入前10位,其他位为0。如果你需要计算那个值,那么左移是最佳选择。

答案 3 :(得分:0)

如何在C中结合使用联合字段?以下结构允许您设置整个32位值,前10位或后22位。它不像通用功能那样通用,但在使用它时不容易出错。请注意这一点,并且大多数解决方案可能不适用于所有整数大小,并且也会注意字节顺序。

union uu {
    struct {
        uint32_t bottom22 : 22;
        uint32_t top10 : 10;
    } bits;
    uint32_t value;
};

以下是一个示例用法:

int main(void) {
    union uu myuu;
    myuu.value = 999999999;
    printf("value = 0x%08x\n", myuu.value);

    myuu.bits.top10 = 0;
    printf("value = 0x%08x\n", myuu.value);

    myuu.bits.top10 = 0xfff;
    printf("value = 0x%08x\n", myuu.value);

    return 0;
}

输出结果为:

value = 0x3b9ac9ff
value = 0x001ac9ff
value = 0xffdac9ff

答案 4 :(得分:0)

您还可以采用掩码替换方法,将保留123所需的低位归零,然后只需|(< strong> OR )用123获取最终结果的值。您可以通过其他几个答案所示的班次完成相同的操作,或者您可以使用蒙版完成它:

#include <stdio.h>

#ifndef BITS_PER_LONG
#define BITS_PER_LONG 64
#endif

#ifndef CHAR_BIT
#define CHAR_BIT 8
#endif

char *binpad2 (unsigned long n, size_t sz);

int main (void) {


    unsigned x = 0b11101010101010110101100100010010;
    unsigned mask = 0xffffff00; /* mask to zero lower 8 bits  */
    unsigned y = 123;           /* value to replace zero bits */

    unsigned masked = x & mask; /* zero the lower bits        */

    /* show intermediate results */
    printf ("\n x      : %s\n", binpad2 (x, sizeof x * CHAR_BIT));
    printf ("\n & mask : %s\n", binpad2 (mask, sizeof mask * CHAR_BIT));
    printf ("\n masked : %s\n", binpad2 (masked, sizeof masked * CHAR_BIT));
    printf ("\n | 123  : %s\n", binpad2 (y, sizeof y * CHAR_BIT));

    masked |= y;    /* apply the final or with 123 */

    printf ("\n final  : %s\n", binpad2 (masked, sizeof masked * CHAR_BIT));


    return 0;
}

/** returns pointer to binary representation of 'n' zero padded to 'sz'.
 *  returns pointer to string contianing binary representation of
 *  unsigned 64-bit (or less ) value zero padded to 'sz' digits.
 */
char *binpad2 (unsigned long n, size_t sz)
{
    static char s[BITS_PER_LONG + 1] = {0};
    char *p = s + BITS_PER_LONG;
    register size_t i;

    for (i = 0; i < sz; i++)
        *--p = (n>>i & 1) ? '1' : '0';

    return p;
}

<强>输出

$ ./bin/bitsset

 x      : 11101010101010110101100100010010

 & mask : 11111111111111111111111100000000

 masked : 11101010101010110101100100000000

 | 123  : 00000000000000000000000001111011

 final  : 11101010101010110101100101111011