KBh
KBh

Reputation: 53

how can I create a bitmaped data in c?

I am trying to create a bitmaped data in , here is the code I used but I am not able to figure the right logic. Here's my code

bool a=1;
bool b=0;
bool c=1;
bool d=0;

uint8_t output = a|b|c|d;

printf("outupt = %X", output);

I want my output to be "1010" which is equivalent to hex "0x0A". How do I do it ??

Upvotes: 5

Views: 124

Answers (3)

0___________
0___________

Reputation: 67476

C only

I would use bitfields. I know that they are not portable, but for the particular embedded hardware (especially uCs) it is well defined.

#include <string.h>
#include <stdio.h>
#include <stdbool.h>


typedef union 
{
    struct 
    {
        bool a:1;
        bool b:1;
        bool c:1;
        bool d:1;
        bool e:1;
        bool f:1;
    };
    unsigned char byte;
}mydata;


int main(void)
{
    mydata d;

    d.a=1;
    d.b=0;
    d.c=1;
    d.d=0;

printf("outupt = %hhX", d.byte);
}

Upvotes: -1

Christophe
Christophe

Reputation: 73366

If you're interested in setting/clearing/accessing very simply specific bits, you could consider std::bitset:

bitset<8> s;   // bit set of 8 bits

s[3]=a;        // access individual bits, as if it was an array
s[2]=b;
s[1]=c; 
s[0]=d;        // the first bit is the least significant bit

cout << s <<endl;       // streams the bitset as a string of '0' and '1' 
cout << "0x"<< hex << s.to_ulong()<<endl;    // convert the bitset to unsigned long
cout << s[3] <<endl;     // access a specific bit
cout << "Number of bits set: " << s.count()<<endl; 

Online demo

The advantage is that the code is easier to read and maintain, especially if you're modifying bitmapped data. Because setting specific bits using binary arithmetics with a combination of << and | operators as explained by Anttii is a vorkable solution. But clearing specific bits in an existing bitmap, by combining the use of << and ~ (to create a bit mask) with & is a little more tricky.

Another advantage is that you can easily manage large bitsets of hundreds of bits, much larger than the largest built-in type unsigned long long (although doing so will not allow you to convert as easily to an unsigned long or an unsigned long long: you'll have to go via a string).

Upvotes: 0

The bitwise or operator ors the bits in each position. The result of a|b|c|d will be 1 because you're bitwise oring 0 and 1 in the least significant position.

You can shift (<<) the bits to the correct positions like this:

uint8_t output = a << 3 | b << 2 | c << 1 | d;

This will result in

    00001000 (a << 3)
    00000000 (b << 2)
    00000010 (c << 1)
  | 00000000 (d; d << 0)
    --------
    00001010 (output)

Strictly speaking, the calculation happens with ints and the intermediate results have more leading zeroes, but in this case we do not need to care about that.

Upvotes: 7

Related Questions