按位操作或按位编程

4
我知道位运算符、位操作、二进制补码等概念。但是在使用位操作解决问题时,我并不容易想到它们。我需要花费时间来理解它们。
我认为查看一些关于位运算符/位操作的问题可能会有所帮助,但是这让我更加困惑如何处理这个主题。我不是在寻找特定问题的答案,而是在处理位操作时寻找一般化的方法/思路。谢谢。

我认为特定的问题需要特定的方法... - EboMike
面试官会问这些问题吗?如果是,会问哪些问题? - Dan
2
你可以查看这个列表,了解一些有趣的位操作应用:http://www.cs.utk.edu/~vose/c-stuff/bithacks.html - Naveen
你也可以在SO上回顾一些关于位运算的好问题和答案。 - Paul R
我会说熟能生巧。你可以在http://graphics.stanford.edu/~seander/bithacks.html上练习位运算问题。 - SiLent SoNG
5个回答

6
到目前为止给出的答案都没有什么用。但是Naveen给出的链接帮了我一点忙。这里提供了很多例子,我正在试着从中学习。也许这会对其他人有所帮助。 位操作技巧 更新: 我已经浏览了上面链接中给出的例子。它们很好。并且我在SO上偶然发现了位运算编程资源链接。这是一个很棒的资源。浏览完所有这些资源后,我感觉位运算编程很容易!从来没有想过我会在句子中使用这个词 :)

1
看起来你链接的页面已经被移动了。禁止访问。该网站链接到以下地址:http://graphics.stanford.edu/~seander/bithacks.html - Jeff Mercado
@Jeff。是的!谢谢。我也更新了帖子! - Srikar Appalaraju

2

我猜测您的问题是:

在处理位运算问题时,我应该采取什么方法和思维方式?

如果我猜对了,请继续阅读,否则请停止...

对于像我这样的初学者来说,位运算是一个困难的主题。我需要集中精力,仔细注意,并通过一组分级示例问题来学习。我会定期复习所学内容。


1
但是当涉及到使用位运算来解决问题时,它并没有让我想起来。
"把C变量看作一个二进制字符串,数据由这个二进制字符串表示"
我编写了一个示例程序,以非常简单的方式说明了位操作,我从这个示例开始操纵某些变量的位,并意识到使用辅助函数dec2bin(number, size_of_the_data)进行了更改。
我们可以很容易地学习使用变量(数据)的说明性二进制部分进行位操作。例如,如果我们有一个包含ASCII字符“b”的字符(char)变量,要使其成为大写字符“B”,我们需要将第6位比特从1更改为0(请记住,char类型具有8位可用(取决于系统架构)),首先在脑海中表达的操作为c xor 0x20(对于C语言表达式将是c ^ = 0x20); 解释: b-0110 0010-转换为大写B-0100 0010(如何) 我们需要处理位号为6的位,将其从true (小写)更改为false,这将把变量的内容转换为大写字符。查看AND、OR、XOR、NOT真值表,我们选择XOR真值表,因为逻辑理论属性1 xor 1的结果是0位值,在C中,此操作表示为^。那么0x20是一个十六进制掩码,在二进制(2)0010 0000(0)中,该表达式表示为0110 0010 xor 0010 0000 => 0100 0010是大写字符'B'。我们会发现,大写字符'B' xor 掩码将导致小写字符'b'。
通过使用这个程序,我们会发现位运算非常容易理解。
#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");
}

0

那么你具体是在寻找什么呢?说实话,这看起来有点模糊。你是否读过一本关于C语言的书籍?或许你可以查阅一些代码示例,了解如何在C语言中处理一些标准编程解决方案。


0

通过编写自己的紧凑、跨平台的二进制协议来发送对象消息,我学到了很多关于这方面的知识(例如网络套接字)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接