按位操作或按位编程

时间:2010-09-23 06:38:36

标签: c++ c bit-manipulation

我知道逐位运算符,位操作,2的补码等概念。但是当谈到使用位操作来解决某些问题时,它并没有让我感到震惊。我花时间把头包住了。

我认为如果我查看有关位操作符/位操作的一些问题会有所帮助,但是让我对如何处理这个主题更加困惑。我不是在寻找特定问题的答案,而是在处理位操作时寻找一种通用的方法/思维方式。感谢。

5 个答案:

答案 0 :(得分:6)

到目前为止给出的答案远非有用。但是Naveen给出的链接对我有所帮助。这里给出了很多例子。我正在努力向他们学习。也许它会帮助别人。

Bit Hacks

更新:我一直在浏览上面链接中给出的示例。他们很好。 我偶然发现了 - Resource for Bitwise Programming链接。优秀的资源。经过所有这些资源后,我觉得按位编程很容易!从来没有想过我会在一句话中使用它:)

答案 1 :(得分:2)

我认为你的问题是:

  

我应该采取什么方法,以及采取什么方法   在应对时我应该采用什么样的心态   涉及位操作的问题?

如果这是正确的,请继续阅读,如果没有,请立即停止......

  

位操作是一个难题   对于像我这样的初学者。我会   必须集中精力并付出代价   我努力工作时要小心   分级样本问题集。我会   修改我经常学到的东西   间隔。

答案 2 :(得分:1)

  

但是当谈到使用位操作解决某些问题时,它确实如此   没有打击我

"将C变量视为二进制字符串,数据由此二进制字符串表示"

我构建了一个示例程序,以非常简单的方式说明对位的操作,我从这个示例开始操作某些变量位并实现使用辅助函数dec2bin(number,size_of_the_data)所做的更改。

我们可以使用变量(数据)的说明性二进制部分来学习非常简单的位操作。 例如,如果我们有一个变量字符(char),其中包含ASCII字符' b'为了形成一个大写字母' B'我们需要操作位数6(记住类型char有8位可用(取决于系统架构))从1到0,首先考虑操作是表示为c xor 0x20(对于C语言表达式将是c ^ = 0x20);

<强>解释

b - 0110 0010 - 大写B - 0100 0010(怎么样?)

我们需要处理设置为true(小写)的第六位为false,这会将变量的内容转换为大写字符。 查看真值表AND,OR,XOR,不是我们将选择的真值表将是XOR真值表,因为逻辑理论属性1 xor 1导致0位值,在C中此操作被表示为^。 0x20是二进制(2)0010 0000(0)中的十六进制掩码,该表达式表示0110 0010 xor 0010 0000 =&gt; 0100 0010是大写字母&#39; B&#39; 我们将观察到资本特征&#39; B&#39; xor掩码将产生小写字符&#39; b&#39;。

使用这个程序,我们会发现按位操作非常容易理解。

#include <stdio.h>
#include <stdlib.h>

void dec2bin(signed long long int, unsigned short size);

int main()
{
    signed long long int packedData = 0xABC4F0DE;

    signed long long int testData = -0xFF;
    dec2bin(testData, sizeof(signed long long int));

    /*
     *  NOTE:
     *  -----
     *  All printed instructions are virtually and are garbage
     *  instructions (not used anywhere in programming).
     *  That instructions are supposed to make current operation visible.
     */
    //Garbage data (random which calls for a global complex subroutine)
    printf("Istruction  1: [RND [__global__]     ] ");
    dec2bin(packedData, sizeof(unsigned long int));

    // NULL the data - CLR (clear all bits from data)
    // CLR is calling a sobroutine composed with AND 0x0 mask;
    packedData &= 0x0;
    printf("Istruction  2: [CLR [AND 0x0]        ] ");
    dec2bin(packedData, sizeof(signed long int));

    // Adding 0x3A (0011 1010) to packed data
    packedData |= 0x3A;
    printf("Istruction  3: [OR  0x3A             ] ");
    dec2bin(packedData, sizeof(signed long int));

    // Shift to the left this data to next nibble
    packedData <<= 4;
    printf("Istruction  4: [SHL 0x4              ] ");
    dec2bin(packedData, sizeof(signed long int));

    // Shift again to the left this data to next nibble
    packedData <<= 4;
    printf("Istruction  5: [SHL 0x4              ] ");
    dec2bin(packedData, sizeof(signed long int));

    // Adding 0xF (1111) to packed data
    packedData |= 0xF;
    printf("Istruction  6: [OR  0xF              ] ");
    dec2bin(packedData, sizeof(signed long int));

    // Shift again to the left this data to next byte (2 * nibble)
    packedData <<= 8;
    printf("Istruction  7: [SHL 0x8              ] ");
    dec2bin(packedData, sizeof(signed long int));

    // Extract contents of low ordered nibble from second byte (with a mask)
    packedData &= 0x00000F00;
    printf("Istruction  8: [AND 0x00000F00       ] ");
    dec2bin(packedData, sizeof(signed long int));

    // Invert (negate|NAND) each bit from data (invert mask)
    packedData = ~packedData;
    printf("Istruction  9: [INV [NOT XXXXXXXX]   ] ");
    dec2bin(packedData, sizeof(signed long int));

    // Shift to the right this data to previous nibble
    packedData >>= 4;
    printf("Istruction 10: [SHR 0x4              ] ");
    dec2bin(packedData, sizeof(signed long int));

    // Shift to the right this data to previous nibble
    packedData >>= 4;
    printf("Istruction 11: [SHR 0x4              ] ");
    dec2bin(packedData, sizeof(signed long int));

    // Shift to the right this data to previous nibble
    packedData >>= 2;
    printf("Istruction 12: [SHR 0x2              ] ");
    dec2bin(packedData, sizeof(signed long int));

    // Invert (negate|NAND) each bit from data (invert mask)
    packedData = ~(packedData) & 0x00FFFFFF;
    printf("Istruction 13: [INV [NAND 0x00FFFFFF]] ");
    dec2bin(packedData, sizeof(signed long int));

    // Adding 0xF0000000 (1111 0000 ... 0000) to packed data
    packedData |= 0xF0000000;
    printf("Istruction 14: [OR  0xF0000000       ] ");
    dec2bin(packedData, sizeof(signed long int));

    // Shift to the left this data to next nibble
    packedData <<= 4;
    printf("Istruction 15: [SHL 0x4              ] ");
    dec2bin(packedData, sizeof(signed long int));

    // Exclusive or
    packedData ^= 0x0F0000F0;
    printf("Istruction 16: [XOR 0x0F0000F0       ] ");
    dec2bin(packedData, sizeof(signed long int));

    return 0;
}

void dec2bin(signed long long int number, unsigned short size)
{
    int c, k;
    for (c = (size*8)-1; c >= 0; c--)
    {
        k = number >> c;
        if (k & 1)
            printf("1");
        else
            printf("0");
        if (c % 4 == 0)
            printf(" ");
    }
    printf("\n");
}

答案 3 :(得分:0)

那么你究竟想要什么,说实话,这看起来有点模糊。你读过一本关于例如C的书吗?您可以查看一些有关如何在C中处理某些标准编程解决方案的代码示例。

答案 4 :(得分:0)

我通过编写自己的紧凑的跨平台二进制协议来通过流发送对象消息(作为网络套接字),从中学到了很多东西。