按位逻辑用C [英] Bitwise Logic in C

查看:118
本文介绍了按位逻辑用C的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一些熟悉位操作,不过这个功能只是去了我的头。

 无效binary_print(unsigned int类型的值){
  unsigned int类型面膜= 0xff000000; //为最高字节口罩开始。
  unsigned int类型转变= 256 * 256 * 256; //为最高字节偏移开始。
  unsigned int类型字节,byte_iterator,bit_iterator;  为(byte_iterator = 0; byte_iterator 4;; byte_iterator ++){
    字节=(价值&安培;面罩)/班; //隔离每个字节。
    的printf();    为(bit_iterator = 0; bit_iterator&下; 8; bit_iterator ++){
      //输出字节的位。
      如果(字节&放大器; 0x80的)//如果在字节的最高位不是0,
        输出(1); //打印1。
      其他
        输出(0); //否则,打印0。      字节* = 2; //移动1所剩下的全部位的。
    }
    面膜/ = 256; // 8移掩膜权位。
    移动/ = 256; // 8在移动右移位。
  }
}

这个函数接收位标志为的open()功能,并产生了display_flags功能,增加了相应的标签的帮助下面的输出:

  O_RDONLY:0:00000000 00000000 00000000 00000000
O_WRONLY:1:00000000 00000000 00000000 00000001
O_RDWR:2:00000000 00000000 00000000 00000010
O_APPEND:1024:00000000 00000000 00000100 00000000
O_TRUNC:512:00000000 00000000 00000010 00000000
O_CREAT:64:00000000 00000000 00000000 01000000
O_WRONLY | O_APPEND | O_CREAT:1089:00000000 00000000 00000100 01000001

我没有问题,理解输出,但我不明白的实际过程:


  1. 如何字节=(价值&安培;面罩)?/班分离单个位

  2. 为什么如果(字节&安培; 0x80的)?如果该字节的最高位不为0表示

  3. 如何做这些行:字节* = 2; 面膜/ = 256; 换挡/ = 256; 动位,这是为什么操作显著?


解决方案

1。如何字节=(价值&安培;面罩)?/班分离单个位

屏蔽是始终设置为1,连续8位的位模式,其余为0(它与 0xff000000 ,然后 0x00ff0000 ,等等。所以,当你把和屏蔽的按位和,从值的所有位将被设置为0,除了那些对应于由<$ C $指定的字节C>屏蔽。那些保持自己的价值。

设置为相应的值,通过与分工正是那些幸存下来的掩蔽将位在最右边位结束(请参阅回答问题3如何工作)。

所以假设 0xDEADBEEF 屏蔽有其初始值 0xff000000 有其初始值 256 * 256 * 256 。然后价值和放大器;面具 0xDE000000 ,而最终的结果是 0x000000DE

在二进制的例子是

 值= 11011110101011011011111011101111
面膜= 11111111000000000000000000000000
字节&安培;面膜= 11011110000000000000000000000000
结果= 00000000000000000000000001101111

2。为什么如果(字节&安培; 0x80的)?如果该字节的最高位不为0表示

在这里,code笔者认为字节是一个8位的变量。虽然在技术上是越大,位不会被用在这里。所以,当笔者提到了最高位,想从右侧(第8位,这将是那里,如果字节的最高位实际上是大小只有一个字节)。

现在注意, 0x80的千万二进制。所以,当你把字节和放大器; 0x80的,从字节所有位将被设置为0,除了最高(第8右一)之一。因此,字节和放大器; 0x80的为零,如果从字节的最高位为0,且大于零,如果从字节 1

3。如何做这些行:字节* = 2; 面膜/ = 256; 移/ = 256; 动位,这是为什么操作显著

乘法与2相当于比特到移位的由1左​​考虑例如值9,这是 1001 二进制。 2乘法给出了18,这是 10010 二进制。

有由2除法相似,这是向右移位由1部256等同于8分频2,所以除以256相当于由8位右移。
这些操作都在这里用于例如更改值屏蔽 0xff000000 0x00ff0000 0x0000ff00 ,终于 0x000000ff

全功能的的说明

有了这些知识,我们就可以看到完整的功能做了什么。在外环它遍历的4个字节是,从最左边的一个,与最右边的。一个结束。它通过屏蔽出当前的字节,并将其存储字节这样做。

内环然后越过存储在字节 8位。它始终着眼于从右边第8位,并相应地输出1或0。然后将这个位到左侧,这样,在第二次迭代,这是从右侧的第7位,现在是从右侧的第8和将被打印,然后下一个等等,直到所有8位中从右到印刷-left秩序。

写这个功能的另一种方法是

 的for(int i为31; I&GT; = 0;我 - ){
  如果(值及(1下;&所述; i))的
    输出(1);
  其他
    输出(0);  如果(I%8 == 0)
    的printf();
}

这只会经历所有位从左到右的顺序。这位前pression 值(1&LT;&LT; I)选择从所需的位,从从右侧的第32(当 I 31),并从右侧的第一个结束时( I 0)

I have some familiarity with bitwise operations, but this function just went over my head.

void binary_print(unsigned int value) {
  unsigned int mask = 0xff000000;   // Start with a mask for the highest byte.
  unsigned int shift = 256*256*256; // Start with a shift for the highest byte.
  unsigned int byte, byte_iterator, bit_iterator;

  for (byte_iterator=0; byte_iterator < 4; byte_iterator++) {
    byte = (value & mask) / shift; // Isolate each byte.
    printf(" ");

    for (bit_iterator=0; bit_iterator < 8; bit_iterator++) {
      // Print the byte's bits.
      if (byte & 0x80) // If the highest bit in the byte isn't 0,
        printf("1");   // print a 1.
      else
        printf("0");   // Otherwise, print a 0.

      byte *= 2;       // Move all the bits to the left by 1.
    }
    mask /= 256;       // Move the bits in mask right by 8.
    shift /= 256;      // Move the bits in shift right by 8.
  }
}

This function receives bit flags for the open() function and produces the following output with the help of a display_flags function that adds the appropriate labels:

O_RDONLY : 0 : 00000000 00000000 00000000 00000000
O_WRONLY : 1 : 00000000 00000000 00000000 00000001
O_RDWR : 2 : 00000000 00000000 00000000 00000010
O_APPEND : 1024 : 00000000 00000000 00000100 00000000
O_TRUNC : 512 : 00000000 00000000 00000010 00000000
O_CREAT : 64 : 00000000 00000000 00000000 01000000
O_WRONLY|O_APPEND|O_CREAT : 1089 : 00000000 00000000 00000100 01000001 

I have no problem understanding the output, but I don't understand the actual process:

  1. How does byte = (value & mask) / shift isolate individual bits?
  2. Why if(byte & 0x80) means "If the highest bit in the byte isn't 0?"
  3. How do these lines: byte *= 2; , mask /= 256; and shift /= 256; move bits and why is this operation significant?

解决方案

1. How does byte = (value & mask) / shift isolate individual bits?

mask is a bit pattern that always has 8 consecutive bits set to 1, the rest to 0 (it starts with 0xff000000, then 0x00ff0000, and so on. So when you take the bitwise and of mask and value, all bits from value will be set to 0, except those that correspond to the byte that is specified by mask. Those keep their value.

shift is set to the corresponding value that by the division with shift exactly those bits that survived the masking will end up in the rightmost bits (see answer to question 3 how that works).

So assume value is 0xDEADBEEF, mask has its initial value 0xff000000, and shift has its initial value 256*256*256. Then value & mask is 0xDE000000, and the final result is 0x000000DE.

In binary the example would be

value       = 11011110101011011011111011101111
mask        = 11111111000000000000000000000000
byte & mask = 11011110000000000000000000000000
result      = 00000000000000000000000001101111

2. Why if(byte & 0x80) means "If the highest bit in the byte isn't 0?"

Here the code author thinks of byte being an 8-bit variable. Although it is technically larger, the higher bits are never used here. So when the author refers to the "highest bit", think of the 8th bit from the right (the highest bit that would be there if byte was actually only one byte in size).

Now note that 0x80 is 10000000 in binary. So when you take byte & 0x80, all bits from byte will be set to 0, except the "highest" (8th from right) one. So byte & 0x80 is zero, if the highest bit from byte is zero, and greater than zero, if the "highest" bit from byte is 1.

3. How do these lines: byte *= 2;, mask /= 256; and shift /= 256; move bits and why is this operation significant?

Multiplication with 2 is equivalent to a shift of bits to the left by 1. Consider for example the value 9, which is 1001 in binary. A multiplication by 2 gives 18, which is 10010 in binary.

Similar for a division by 2, this is a shift to the right by 1. Division by 256 is equivalent to 8 divisions by 2, so dividing by 256 is equivalent to a right shift by 8 bits. These operations are used here for example to change the value mask from 0xff000000 to 0x00ff0000, 0x0000ff00, and finally to 0x000000ff.

Description of full function

With this knowledge, we can see what the full function does. In the outer loop it loops over the 4 bytes that are in value, starting with the left-most one and ending with the right-most one. It does so by masking out the current byte and stores it in byte.

The inner loop then goes over the 8 bits that are stored in byte. It always looks at 8th bit from the right and prints 1 or 0 accordingly. Then it shifts the bits to the left, so that in the second iteration the bit that was the 7th from right is now the 8th from right and will be printed, and then next one etc. until all 8 bits are printed in right-to-left order.

An alternative way to write this function would be

for (int i = 31; i >= 0; i--) {
  if (value & (1 << i))
    printf("1");
  else
    printf("0");

  if (i % 8 == 0)
    printf(" ");
}

This would simply go through all bits from value in left-to-right order. The expression value (1 << i) selects the desired bit from value, starting with the 32th from right (when i is 31), and ending with the 1st from right (when i is 0).

这篇关于按位逻辑用C的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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