Bitwise indexing in C?

I am trying to implement the idea of ​​data compression that I have, and since I imagine running it against a large array of test data, I thought that I need to encode it in C (I basically have experience in scripting languages ​​like Ruby and Tcl .)

Looking through O'Reilly's "cow" books in C, I realize that I can't just index the bits of a simple variable like "char" or "int", because I would like to compare comparisons and operators in a sizeable way.

Am I correct in this perception? Is it reasonable for me to use an enumerated type to represent a bit (and create an array from them and write functions to convert to and from char)? If so, is this type and function defined in the standard library somewhere else? Are there other (better?) Approaches? Is there any code sample somewhere that anyone could call me?

Thanks -

+7
c coding-style bit-manipulation
source share
9 answers

Following what Kyle said, you can use a macro to do the hard work for you.

Maybe.

To set the nth bit, use OR:

x | = (1 <5); // sets the 6th from right

To clear a bit, use AND:

x & = ~ (1 <5); // clears Sixth-s-right

To flip a bit, use XOR:

x ^ = (1 <5); // flips the 6th right

Or...

#define GetBit(var, bit) ((var & (1 << bit)) != 0) // Returns true / false if bit is set #define SetBit(var, bit) (var |= (1 << bit)) #define FlipBit(var, bit) (var ^= (1 << bit)) 

Then you can use it in code, for example:

 int myVar = 0; SetBit(myVar, 5); if (GetBit(myVar, 5)) { // Do something } 
+10
source share

Maybe.

To set the nth bit, use OR:

 x |= (1 << 5); // sets the 5th-from right 

To clear a bit, use AND:

 x &= ~(1 << 5); // clears 5th-from-right 

To flip a bit, use XOR:

 x ^= (1 << 5); // flips 5th-from-right 

To get the value of bit usage and AND:

 (x & (1 << 5)) >> 5 // gets the value (0 or 1) of the 5th-from-right 

Note: a shift to the right 5 means that the value is either 0 or 1. If you are only interested in 0 / not 0, you can do without a shift.

+7
source share

Look at the answers to this question .

+3
source share

Theory

There is no C syntax for accessing or setting the nth bit of a built-in data type (e.g. a char '). However, you can access the bits using the logical AND operation and set the bits using the logical OR operation.

As an example, let's say that you have a variable that contains 1101, and you want to check the second bit on the left. Just do a logical AND from 0100:

 1101 0100 ---- AND 0100 

If the result is nonzero, then the second bit must be set; otherwise it has not been established.

If you want to set the third bit on the left, then do a logical OR with 0010:

 1101 0010 ---- OR 1111 

You can use the C && (for AND) and || (for OR) to complete these tasks. You will need to create bit access patterns (0100 and 0010 in the examples above). The trick is to remember that the least significant bit (LSB) counts 1 s, the next least significant bit is 2 s, then 4 s, etc. Thus, the bit access pattern for the nth low order bit (starting at 0) is simply a 2 ^ n value. The easiest way to calculate this in C is to shift the binary value 0001 (in this example with four bits) to the left by the required number places Since this value is always 1 in unsigned integers, it is simply '1 <n'

Example

 unsigned char myVal = 0x65; /* in hex; this is 01100101 in binary. */ /* Q: is the 3-rd least significant bit set (again, the LSB is the 0th bit)? */ unsigned char pattern = 1; pattern <<= 3; /* Shift pattern left by three places.*/ if(myVal && (char)(1<<3)) {printf("Yes!\n");} /* Perform the test. */ /* Set the most significant bit. */ myVal |= (char)(1<<7); 

This example has not been tested, but should serve as an illustration of a general idea.

+2
source share

Requesting the status of bits with a specific index:

 int index_state = variable & ( 1 << bit_index ); 

To set the bit:

 varabile |= 1 << bit_index; 

Restart bit:

 variable &= ~( 1 << bit_index ); 
+1
source share

Individual bits can be indexed as follows.

Define a structure like this:

 struct { unsigned bit0 : 1; unsigned bit1 : 1; unsigned bit2 : 1; unsigned bit3 : 1; unsigned reserved : 28; } bitPattern; 

Now, if I want to know the individual bit values ​​of var called "value", do the following:

 CopyMemory( &input, &value, sizeof(value) ); 

To find out if bit 2 is high or low:

 int state = bitPattern.bit2; 

Hope this helps.

+1
source share

If you want to index a bit, you could:

 bit = (char & 0xF0) >> 7; 

gets msb char. You can even leave the right shift and run a test at 0.

 bit = char & 0xF0; 

if the bit is set, the result will be> 0;

Obviously, you need to change the mask to get different bits (NB: 0xF is the bit mask if it is not clear). Numerous masks can be defined, for example.

 #define BIT_0 0x1 // or 1 << 0 #define BIT_1 0x2 // or 1 << 1 #define BIT_2 0x4 // or 1 << 2 #define BIT_3 0x8 // or 1 << 3 

etc...

This gives you:

 bit = char & BIT_1; 

You can use these definitions in the above code to successfully index a bit inside a macro or function.

To set the bit:

 char |= BIT_2; 

To clear a bit:

 char &= ~BIT_3 

To switch the bit

 char ^= BIT_4 

Is this help?

0
source share

There is a standard library container for bits: std :: vector. He specializes in a library to be efficient in area. There is also a dynamic_bitset boost class.

This will allow you to perform operations on a set of logical values ​​using one bit per base storage value.

Enhance dynamic bit documentation

For STL documentation, see the compiler documentation.

Of course, you can also manually access individual bits in other integral types. If you do this, you must use unsigned types so that you do not get undefined behavior if you decide to do the right offset by value with a high set of bits. However, it looks like you want containers.

To the commentator who claimed that it takes 32 times more space than necessary: ​​boost :: dynamic_bitset and vector are specialized for using one bit per record, and therefore there is no penalty for space, assuming that you really want more than the number of bits in primitive type. These classes allow you to access individual bits in a large container with efficient underlying storage. If you just want (say) 32 bits, by all means, use int. If you need a large number of bits, you can use a library container.

0
source share

Try using bit fields. Be careful, the implementation may vary depending on the compiler.

http://publications.gbdirect.co.uk/c_book/chapter6/bitfields.html

0
source share

All Articles