views:

303

answers:

5

I asked the question here and now i would like to reverse this procedure

I have an unsigned short that represents a bit pattern, I would like an array of bool[16] that has true or false set for the corresponding bit in the unsigned short.

so far i have

where binary 2 is an unsigned short, that has the bit pattern i wish to unpack.

unsigned short i;
i = 1<<(sizeof(unsigned short) * 8 - 1);

while (i > 0) {
    if (binary2 & i)
        printf("1");
    else
        printf("0");
    i >>= 1;
}

but i seem to be missing the first bit in my pattern and shifting the remaining ones.

+2  A: 

how about this.

void ExtractBits(int pattern, int array[16])
{
   for (int ii = 0; ii < 16; ++ii)
   {
      array[ii] = pattern & 1;
      pattern = pattern >> 1;
   }
}
John Knoeller
nice and simple.
Aran Mulholland
+3  A: 
 void get_bits(uint16_t pattern, bool bits[16]) {
    for (int i = 0; i < 16; ++ i)
      bits[i] = (pattern & 1 << i) != 0;
 }

union bit16 {
    uint16_t bit_pattern;
    struct {
        int bit0 : 1;
        int bit1 : 1;
        int bit2 : 1;
        int bit3 : 1;
        int bit4 : 1;
        int bit5 : 1;
        int bit6 : 1;
        int bit7 : 1;
        int bit8 : 1;
        int bit9 : 1;
        int bit10 : 1;
        int bit11 : 1;
        int bit12 : 1;
        int bit13 : 1;
        int bit14 : 1;
        int bit15 : 1;
    } bits;
};
KennyTM
Are you sure the union here is portable? Alignment of the struct may be different.
Alex B
@Checkers: He can just move the short to the end of the union to solve any alignment issues.
Robert S. Barnes
You should make your bitfields explicitly unsigned; otherwise they might end up as signed one-bit fields!
Philip Potter
@Robert S. Barnes, does the order matter? They both start at the same address.
Alex B
@Checkers: You're right, my fingers where typing `union`, but my brain was thinking `struct`.
Robert S. Barnes
A: 

Not the best piece of code, but it does the job. You know quick&dirty stuff :)

typedef unsigned short int Word;

bool get_bit(Word word, size_t pos)
{
    return (word &= (1 << pos));
}

void unpack_word(Word word, bool unpacked_bits[])
{
    for(size_t i = 0; i < sizeof(Word)*CHAR_BIT; ++i)
        unpacked_bits[i] = get_bit(word, i);
}

int main()
{
    Word w = 0xF0FF;
    bool bits[sizeof(Word)*CHAR_BIT];
    unpack_word(w, bits);
}
AraK
`std::` is not needed. The question is on C, not C++. (and yes, `bool` exists in C as well (`stdbool.h`).)
KennyTM
@KennyTM Thanks, I forgot to that the question is about C only :)
AraK
A: 

I really don't get why you would want to do this because it sounds like it is slow, but the code to do it should be fairly straight forward. Let me first verify that I understand what you are trying to do. You have an unsigned short and an array of bools. You want to extract each bit in the short into a bool. Correct? If so this should be what you're looking for:

unsigned short bitmask = (some mask);
bool bools[sizeof(unsigned short) * 8];
for(unsigned short i = 0; i < sizeof(unsigned short) * 8; ++i)
{
    unsigned short bit = 1 << i;
    bools[i] = bitmask & bit;
}

Depending on what your application is actually doing I would strongly suggest using enumerations for each bit, and instead of using the bools just do the bitwise and operation against the enum to get the value of the bit. You have to be careful using bitwise operations though because they can be very slow on the CPU.

Also I strongly suggest not using bitfields which Kenny showed in part of his answer because I've never worked on a processor where bitfields are not incredibly slow.

Chris
A: 

So you need something like this;

  for(i = 1, j = 0; i != 0x10000; i <<= 1, ++j)
    result[j] = (binary2 & i) > 0;

For example:

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

bool result[16];

void try(unsigned short binary2) {
  int i,j;

  for(i = 1, j = 0; i != 0x10000; i <<= 1, ++j)
    result[j] = (binary2 & i) > 0;
}

int main(int ac, char **av) {
  int i;

  if (ac > 1)
    try(atoi(av[1]));
  for(i = 15; i >= 0; --i)
    printf("%c", result[i]["ft"]);
  printf("\n");
  return 0;
}
DigitalRoss