What are 0x01 and 0x80 representative of in C bitwise operations?

一曲冷凌霜 提交于 2020-08-02 08:16:16

问题


I'm trying to reverse the order of bits in C (homework question, subject: bitwise operators). I found this solution, but I'm a little confused by the hex values used -- 0x01 and 0x80.

  unsigned char reverse(unsigned char c) {
     int shift;
     unsigned char result = 0;

     for (shift = 0; shift < CHAR_BITS; shift++) {
        if (c & (0x01 << shift))
            result |= (0x80 >> shift);
     }
     return result;
  }

The book I'm working out of hasn't discussed these kinds of values, so I'm not really sure what to make of them. Can somebody shed some light on this solution? Thank you!


回答1:


0x01 is the least significant bit set, hence the decimal value is 1.

0x80 is the most significant bit of an 8-bit byte set. If it is stored in a signed char (on a machine that uses 2's-complement notation - as most machines you are likely to come across will), it is the most negative value (decimal -128); in an unsigned char, is is decimal +128.

The other pattern that becomes second nature is 0xFF with all bits set; this is decimal -1 for signed characters and 255 for unsigned characters. And, of course, there's 0x00 or zero with no bits set.

What the loop does on the first cycle is check if the LSB (least significant bit) is set, and if it is, sets the MSB (most significant bit) in the result. On the next cycle, it checks the next to LSB and sets the next to MSB, etc.

| MSB |     |     |     |     |     |     | LSB |
|  1  |  0  |  1  |  1  |  0  |  0  |  1  |  1  |   Input
|  1  |  1  |  0  |  0  |  1  |  1  |  0  |  1  |   Output
|  1  |  0  |  0  |  0  |  0  |  0  |  0  |  0  |   0x80
|  0  |  0  |  0  |  0  |  0  |  0  |  0  |  1  |   0x01
|  0  |  1  |  0  |  0  |  0  |  0  |  0  |  0  |   (0x80 >> 1)
|  0  |  0  |  0  |  0  |  0  |  0  |  1  |  0  |   (0x01 << 1)



回答2:


Each hex digit represents 4bits, so

  • 0x01 is just a long way of writing 1.
  • 0x80 is a short way of writing in binary [1000][0000], or 128.

The solution is using bitwise operators to test and set values.

The expression:

if (a & b) { ... }

executes '...' if the same bit is 1 in both 'a' and 'b'.

The expression

c |= b

sets the bits in 'c' to 1, if they are 1 in 'b'.

The loop moves the test & set bit down the line.

Good luck!




回答3:


The values 0x01 and 0x80 are purposely written in hexadecimal notation to underscore their significance as the least significant and the most significant bits of the type unsigned char.

Yet the author made several mistakes:

  • the macro CHAR_BITS is misspelled: it should be CHAR_BIT.
  • using CHAR_BIT instead of hard-coding the almost universal value 8 is a valuable effort for complete portability, yet this effort is nullified by the use of 0x80 which is only valid if CHAR_BIT == 8.
  • there is another subtle portability problem: 0x01 << shift would have undefined behavior for shift = CHAR_BIT-1 on a platform where sizeof(unsigned char) == sizeof(int) because 0x01 has type int (and not unsigned int, counter-intuitive is it not?).

Here is a corrected version that works on all conformant platforms:

#include <limits.h>

unsigned char reverse(unsigned char c) {
    int shift;
    unsigned char result = 0;

    for (shift = 0; shift < CHAR_BIT; shift++) {
        result <<= 1;
        result |= c & 1;
        c >>= 1;
    }
    return result;
}



回答4:


0x01 means 1—a one in the ones place—and 0x80 means 128—an 8 in the sixteens place. Those numbers refer to the lowest bit and highest bit in an eight-bit number, respectively. Shifting them gives masks for the individual bits in the byte.

Edit: In a hexadecimal number, the digits go in powers of sixteen, not powers of ten. So the first digit from the right is the ones place (0x1 = 1), the second digit is the sixteens place (0x10 = 16), the third digit is the two-hundred-fifty-sixes place (0x100 = 256), and so on.



来源:https://stackoverflow.com/questions/2660484/what-are-0x01-and-0x80-representative-of-in-c-bitwise-operations

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!