I have a 3d boolean array of the following dimensions:
bool myArray[streamCount][dayCount][minuteCount];
where
dayCount = 500, streamCount = 11,000 and minuteCount = 400;
I am trying to dramatically shrink the memory requirements of this array by using bit packing.
I need to retain the ability to randomly access any of the values, in the same way I do now with the 3d array.
Below is the (brain-dead) scheme I devised. It has the problem that to find the value, I need to set up
8 if statements. Is there an easier way to do this?
#define STREAM_COUNT 11000
#define DAY_COUNT 500
typedef struct s_minuteStorage
{
unsigned char a: 1;
unsigned char b: 1;
unsigned char c : 1;
unsigned char d : 1;
unsigned char e: 1;
unsigned char f: 1;
unsigned char g : 1;
unsigned char h : 1;
} minuteStorage;
typedef struct s_itemStorage
{
minuteStorage Minutes[STREAM_COUNT][50];
} itemStorage;
itemStorage *Items;
void allocStorage(void)
{
Items = (itemStorage *) ecalloc(DAY_COUNT, 1);
}
int getMinuteValue(int minuteIndex, int dayIndex, int streamIndex)
{
int minuteArrayIndex = minuteIndex / 8;
int remainder = minuteIndex % 8;
int value;
if (remainder == 0)
value = Items[dayIndex].Minutes[streamIndex][minuteArrayIndex].a;
if (remainder == 1)
value = Items[dayIndex].Minutes[streamIndex][minuteArrayIndex].b;
if (remainder == 2)
value = Items[dayIndex].Minutes[streamIndex][minuteArrayIndex].c;
// etc
return(value);
}
Instead of using a struct, you can just use an unsigned char and shift by the proper number of bits:
typedef unsigned char minuteStorage;
int getMinuteValue(int minuteIndex, int dayIndex, int streamIndex)
{
int minuteArrayIndex = minuteIndex / 8;
int remainder = minuteIndex % 8;
minuteStorage m = Items[dayIndex].Minutes[streamIndex][minuteArrayIndex];
return (m >> remainder) & 1;
}
Related
Hi all I am writing a C program that asks the user for an unsigned integer. The program will then call a function
unsigned int reverse_bits(unsigned int n)
This function should return an unsigned integer whose bits are the same as those of n but in reverse
order.
Print to screen the integer whose bits are in reverse order.
Example:
User enters:
12 (binary 16 bits is 0000000000001100)
Program print to screen:
12288 (0011000000000000)
This is the code i have but it does not output the right answer:
#include <stdio.h>
//function prototype
unsigned int reverse_bits(unsigned int n);
int main(void) {
unsigned int n;
unsigned int bits;
printf("Enter an unsigned integer: ");
scanf("%u",&n);
bits = reverse_bits(n);
printf("%u\n",bits);
return 0;
}
unsigned int reverse_bits(unsigned int n) {
unsigned int reverse = 0;
while (n > 0) {
reverse = reverse << 1;
if((n & 1) == 1) {
reverse = reverse | 1;
}
n = n >> 1;
}
return reverse;
}
This does not give me 12288 when I enter 12, it gives me 3, what did I do wrong?
The result depends on how many bits an unsigned int is stored on your machine. It is usually 4 bytes (32 bits). So, in your case 12 (00000000000000000000000000001100 in binary) becames 805306368 (00110000000000000000000000000000 in binary).
Apart from that, you need to iterate over all bits of an unsigned int:
for (size_t i = 0; i < sizeof(unsigned int) * 8; i++) {
reverse = reverse << 1;
if((n & 1) == 1) {
reverse = reverse | 1;
}
n = n >> 1;
}
This is about ANSI-C (C90). This is what I know:
I can directly tell the compiler how many bits I want for a specific variable.
If I want 1 bit which can have the values zero or one.
or 2 bits for the values 0,1,2,3, and so on...;
I'm familiar with the syntax.
I have problem concerning bitfields:
I want to define a SET structure.
It can have maximum 1024 elements (it can have less, but the maximum is 1024 elements).
The domain of the set is from 1 to 1024. So an element could have any value 1-1024.
I'm trying to create a structure for a SET, and it must be efficient as possible for the memory part.
I tried:
typedef struct set
{
unsigned int var: 1;
} SET;
//now define an array of SETS
SET array_of_sets[MAX_SIZE] //didn't define MAX_SIZE, but no more than 1024 elements in each set.
I know this isn't efficient; maybe it's even not good for what I want. That's why I'm looking for help.
As noted in extensive comments, using a bit field is not the way to go. You can use just 128 bytes of storage for your set containing values 1..1024. You will need to map the value N to bit N-1 (so you have bits 0..1023 to work with). You also need to decide on the operations you need for your set. This code supports 'create', 'destroy', 'insert', 'delete' and 'in_set'. It does not support iteration over the elements in the set; that can be added if you want it.
sets.h
#ifndef SETS_H_INCLUDED
#define SETS_H_INCLUDED
typedef struct Set Set;
enum { MAX_ELEMENTS = 1024 };
extern Set *create(void);
extern void destroy(Set *set);
extern void insert(Set *set, int value);
extern void delete(Set *set, int value);
extern int in_set(Set *set, int value);
#endif /* SETS_H_INCLUDED */
sets.c
#include "sets.h"
#include <assert.h>
#include <limits.h>
#include <stdlib.h>
#include <string.h>
typedef unsigned long Bits;
#define BITS_C(n) ((Bits)(n))
enum { ARRAY_SIZE = MAX_ELEMENTS / (sizeof(Bits) * CHAR_BIT) };
struct Set
{
Bits set[ARRAY_SIZE];
};
Set *create(void)
{
Set *set = malloc(sizeof(*set));
if (set != 0)
memset(set, 0, sizeof(*set));
return set;
}
void destroy(Set *set)
{
free(set);
}
void insert(Set *set, int value)
{
assert(value >= 1 && value <= MAX_ELEMENTS);
value--; /* 0..1023 */
int index = value / (sizeof(Bits) * CHAR_BIT);
int bitnum = value % (sizeof(Bits) * CHAR_BIT);
Bits mask = BITS_C(1) << bitnum;
/* printf("I: %d (%d:%d:0x%.2lX)\n", value+1, index, bitnum, mask); */
set->set[index] |= mask;
}
void delete(Set *set, int value)
{
assert(value >= 1 && value <= MAX_ELEMENTS);
value--; /* 0..1023 */
int index = value / (sizeof(Bits) * CHAR_BIT);
int bitnum = value % (sizeof(Bits) * CHAR_BIT);
Bits mask = BITS_C(1) << bitnum;
/* printf("D: %d (%d:%d:0x%.2lX)\n", value+1, index, bitnum, mask); */
set->set[index] &= ~mask;
}
/* C90 does not support <stdbool.h> */
int in_set(Set *set, int value)
{
assert(value >= 1 && value <= MAX_ELEMENTS);
value--; /* 0..1023 */
int index = value / (sizeof(Bits) * CHAR_BIT);
int bitnum = value % (sizeof(Bits) * CHAR_BIT);
Bits mask = BITS_C(1) << bitnum;
/* printf("T: %d (%d:%d:0x%.2lX) = %d\n", value+1, index, bitnum, mask,
(set->set[index] & mask) != 0); */
return (set->set[index] & mask) != 0;
}
#include <stdio.h>
enum { NUMBERS_PER_LINE = 15 };
int main(void)
{
Set *set = create();
if (set != 0)
{
int i;
int n = 0;
for (i = 1; i <= MAX_ELEMENTS; i += 4)
insert(set, i);
for (i = 3; i <= MAX_ELEMENTS; i += 6)
delete(set, i);
for (i = 1; i <= MAX_ELEMENTS; i++)
{
if (in_set(set, i))
{
printf(" %4d", i);
if (++n % NUMBERS_PER_LINE == 0)
{
putchar('\n');
n = 0;
}
}
}
if (n % NUMBERS_PER_LINE != 0)
putchar('\n');
destroy(set);
}
return 0;
}
The functions should really be given a systematic prefix, such as set_. The BITS_C macro is based on the INT64_C macro (and the other related macros) defined in <stdint.h> in C99 and later, which is also not a part of C90.
As per my previous comments, here is an example of how you can pack eight 1-bit elements into one char physical element.
I have only implemented the function to get the value of a 1-bit element, I leave the function to set it to you (it's easy to do).
Note: you can easily change the type of the array element (unsigned char) and experiment with types which can hold more bits (e.g unsigned int) and test if they perform better in terms of speed.
You can also modify the code to make it handle elements bigger than one bit.
#include <stdio.h>
#include <limits.h>
unsigned int get_el(unsigned char* array, unsigned int index)
{
unsigned int bits_per_arr_el = sizeof(unsigned char)*CHAR_BIT;
unsigned int arr_index = index / bits_per_arr_el;
unsigned int bit_offset = index % bits_per_arr_el;
unsigned int bitmask = 1 << bit_offset;
unsigned int retval;
// printf("index=%u\n", index);
// printf("bits_per_arr_el=%u\n", bits_per_arr_el);
// printf("arr_index=%u\n", arr_index);
// printf("bit_offset=%u\n", bit_offset);
retval = array[arr_index] & bitmask ? 1 : 0; // can be simpler if only True/False is needed
return(retval);
}
#define MAX_SIZE 10
unsigned char bitarray[MAX_SIZE];
int main()
{
bitarray[1] = 3; // 00000011
printf("array[7]=%u, array[8]=%u, array[9]=%u, array[10]=%u\n",
get_el(bitarray, 7),
get_el(bitarray, 8),
get_el(bitarray, 9),
get_el(bitarray,10));
return 0;
}
outputs
array[7]=0, array[8]=1, array[9]=1, array[10]=0
typedef struct set
{
unsigned short var:10; // uint var:1 will be padded to 32 bits
} SET; // ushort var:10 (which is max<=1024) padded to 16 bits
As was commented by #Jonathan Leffler use array(unsigned short[])
and define bitmasks
#define bitZer 0x00 //(unsigned)(0 == 0)? true:true;
#define bitOne 0x10 // so from (both inclusive)0-1023 = 1024
... // added for clarification
#define bitTen 0x0A
to look into the bits of each element.
http://www.catb.org/esr/structure-packing/ detailed
To store a value from 0 to 1023 (or from 1 to 1024, which is essentially the same and only involves adding/subtracting 1) you need a minimum of 10 bits.
This means that for 32-bit (unsigned) integers, you can pack 3 values into 30 bits, which gives 2 bits of useless padding.
Example:
%define ELEMENTS 100
uint32_t myArray[ (ELEMENTS + 2) / 3 ];
void setValue(int n, int value) {
uint32_t temp;
uint32_t mask = (1 << 10) - 1;
if(n >= ELEMENTS) return;
value--; // Convert "1 to 1024" into "0 to 1023"
temp = myArray[n / 3];
mask = mask << (n % 3)*10;
temp = (temp & ~mask) | (value << (n % 3)*10);
myArray[n / 3] = temp;
}
int getValue(int n) {
uint32_t temp;
uint32_t mask = (1 << 10) - 1;
if(n >= ELEMENTS) return 0;
temp = myArray[n / 3];
temp >>= (n % 3)*10;
return (temp & ~mask) + 1;
}
You can do this with bitfields instead, but the code to get/set individual values will end up using branches (e.g. switch( n%3 )) which will be slower in practice.
Removing those 2 bits of padding will cost a little more complexity and a little more overhead. For example:
%define ELEMENTS 100
uint32_t myArray[ (ELEMENTS*10 + 31) / 32 ];
int getValue(int n) {
uint64_t temp;
uint64_t mask = (1 << 10) - 1;
if(n >= ELEMENTS) return 0;
temp = myArray[n*10/32 + 1];
temp = (temp << 32) | myArray[n*10/32];
temp >>= (n*10 % 32);
return (temp & ~mask) + 1;
}
This can't be done with bitfields. This is the most space efficient way to store an array of values that range from 1 to 1024.
If you are storing an "array of booleans" or setting flags, it can be useful. For instance, you can initialize or compare up to 64 values at a time.
These macros will work for unsigned char, short, int, long long ... but simplifies significantly if you just pick a type (so you can use a safer static inline function)
#define getbit(x,n) x[n/(sizeof(*x)*8)] & (typeof(*x))1 << (n&((sizeof(*x)*8)-1))
#define setbit(x,n) x[n/(sizeof(*x)*8)] |= (typeof(*x))1 << (n&((sizeof(*x)*8)-1))
#define flpbit(x,n) x[n/(sizeof(*x)*8)] ^= (typeof(*x))1 << (n&((sizeof(*x)*8)-1))
#define clrbit(x,n) x[n/(sizeof(*x)*8)] &= ~( (typeof(*x))1 << (n&((sizeof(*x)*8)-1)) )
to initialize a large array of booleans all you need to do is: char cbits[]={0,0xF,0,0xFF};
or for all zeroes char cbits[4]={0};
or an int example: int ibits[]={0xF0F0F0F0,~0};
//1111000011110000111100001111000011111111111111111111111111111111
If you will only be accessing 1 type of array, it may be better to make the macros into proper functions like:
static inline unsigned char getbit(unsigned char *x, unsigned n){
return x[n>>3] & 1 << (n&7);
}
//etc... similar for other types and functions from macros above
You can also compare multiple flags at a time by '|'ing the flags together and using '&'ed masks; however, it does get a bit more complex when you exceed the native types
For your particular instance you can initialize to all zeroes by:
unsigned char flags[128]={0};
or all 1's by:
uint64_t flags[128] = {~0,~0,~0,~0,~0,~0,~0,~0,~0,~0,~0,~0,~0,~0,~0,~0};
You can even use enums to name your flags
enum{
WHITE, //0
RED, //1
BLUE, //2
GREEN, //3
...
BLACK //1023
}
if (getbit(flags,WHITE) && getbit(flags,RED) && getbit(flags,BLUE))
printf("red, white and blue\n");
1) The proper solution for this question is to use Bit Array
The question provided the solution with Bit Fields with Struct. There are two typical ways to save memory space for bits related problem, another is to use Bit Array. For this specific case in the question, the better way is to use Bit Array (demoed as follows).
If it is the case like purely independent bit flags here, go
for the Bit Array
If there is a group of relevant bits , such as the IP address or Control Word definition, then it's better to combine them with a struct, that is to use Bit Fields with Sturct
2) Sample code just for demo Bit Array
#include<limits.h>
#define BITS_OF_INT (sizeof(int)*CHAR_BIT)
void SetBit(int A[], int k)
{
//Set the bit at the k-th position
A[k/BITS_OF_INT] |= 1 <<(k%BITS_OF_INT);
}
void ClearBit(int A[], int k)
{
//RESET the bit at the k-th position
A[k/BITS_OF_INT] &= ~(1 <<(k%BITS_OF_INT)) ;
}
int TestBit(int A[], int k)
{
// Return TRUE if bit set
return ((A[k/BITS_OF_INT] & (1 <<(k%BITS_OF_INT)))!= 0) ;
}
#define MAX_SIZE 1024
int main()
{
int A[MAX_SIZE/BITS_OF_INT];
int i;
int pos = 100; // position
for (i = 0; i < MAX_SIZE/BITS_OF_INT; i++)
A[i] = 0;
SetBit(A, pos);
if (TestBit(A, pos)){//do something}
ClearBit(A, pos);
}
3) Furthermore, a worthwhile discussing point from this question is,
How to choose a proper solution between "Bit Array" and "Bit fields with struct"?
Here are some references about this topic.
When to use bit-fields in C?
Readable and Maintainable Bitfields in C
Say I have a two dimensional array where each entry contains a length and a value:
int array[4][2] = { /* {length, value}, */
{5, 3},
{6, 7},
{1, 0},
{8, 15},
};
I want to store them sequentially into memory with leading zeros to make each field the appropriate length. The example above would be:
00011 000111 0 00001111
The first block is five bits long and stores decimal 3. The second block is six bits long and stores decimal seven. The third block is one bit long and stores decimal 0, and the last block is eight bits long and stores decimal 15.
I can do it with some bitwise manipulation but I thought I would ask to see if there is an easier way.
I am coding in C for a Tensilica 32-bit RISC processor.
The purpose is to write a sequence of Exponential-Golomb codes.
EDIT: SOLUTION:
int main(int argc, char *argv[])
{
unsigned int i = 0, j = 0;
unsigned char bit = 0;
unsigned int bit_num = 0;
unsigned int field_length_bits = 0;
unsigned int field_length_bytes = 0;
unsigned int field_array_length = 0;
unsigned int field_list[NUM_FIELDS][2] = {
/*{Length, Value},*/
{4, 3},
{5, 5},
{6, 9},
{7, 11},
{8, 13},
{9, 15},
{10, 17},
};
unsigned char *seq_array;
// Find total length of field list in bits
for (i = 0; i < NUM_FIELDS; i++)
field_length_bits += field_list[i][LENGTH];
// Number of bytes needed to store FIELD parameters
for (i = 0; i < (field_length_bits + i) % 8 != 0; i++) ;
field_length_bytes = (field_length_bits + i) / 8;
// Size of array we need to allocate (multiple of 4 bytes)
for (i = 0; (field_length_bytes + i) % 4 != 0; i++) ;
field_array_length = (field_length_bytes + i);
// Allocate memory
seq_array = (unsigned char *) calloc(field_array_length, sizeof(unsigned char));
// Traverse source and set destination
for(i = 0; i < NUM_FIELDS; i++)
{
for(j = 0; j < field_list[i][LENGTH]; j++)
{
bit = 0x01 & (field_list[i][VALUE] >> (field_list[i][LENGTH] - j - 1));
if (bit)
setBit(seq_array, field_array_length, bit_num, 1);
else
setBit(seq_array, field_array_length, bit_num, 0);
bit_num++;
}
}
return 0;
}
void setBit(unsigned char *array, unsigned int array_len, unsigned int bit_num, unsigned int bit_value)
{
unsigned int byte_location = 0;
unsigned int bit_location = 0;
byte_location = bit_num / 8;
if(byte_location > array_len - 1)
{
printf("setBit(): Unauthorized memory access");
return;
}
bit_location = bit_num % 8;
if(bit_value)
array[byte_location] |= (1 << (7-bit_location));
else
array[byte_location] &= ~(1 << (7-bit_location));
return;
}
You can use a bitstream library:
Highly recommended bitstream library:
http://cpansearch.perl.org/src/KURIHARA/Imager-QRCode-0.033/src/bitstream.c
http://cpansearch.perl.org/src/KURIHARA/Imager-QRCode-0.033/src/bitstream.h
Because this bitstream library seems to be very self-contained, and doesn't seem to require external includes.
http://www.codeproject.com/Articles/32783/CBitStream-A-simple-C-class-for-reading-and-writin - C library, but using windows WORD, DWORD types (you can still typedef to use this library)
http://code.google.com/p/youtube-mobile-ffmpeg/source/browse/trunk/libavcodec/bitstream.c?r=8 - includes quite a few other include files to use the bitstream library
If you just want exponential golomb codes, there are open-source C implementations:
http://www.koders.com/c/fid8A317DF502A7D61CC96EC4DA07021850B6AD97ED.aspx?s=gcd
Or you can use bit manipulation techniques.
For example:
unsigned int array[4][2] = ???
unsigned int mem[100] = {};
int index=0,bit=0;
for (int i=0;i<4;i++) {
int shift = (32 - array[i][0] - bit);
if (shift>0) mem[index] &= array[i][1] << shift;
else {
mem[index] &= array[i][1] >> -shift;
mem[index+1] &= array[i][1] << (32+shift);
}
bit += array[i][1];
if (bit>=32) {
bit-=32;
index++;
}
}
Disclaimer:
The code only works if your computer byte-order is little endian, and the result will actually be little-endian within each 4-byte boundary, and big-endian across 4-byte boundaries. If you convert mem from int type to char, and replace the constants 32 to 8, you will get a big-endian representation of your bit-array.
It also assumes that the length is less than 32. Obviously, the code you actually want will depend on the bounds of valid input, and what you want in terms of byte-ordering.
Do you mean something like a bit field?
struct myBF
{
unsigned int v1 : 5;
unsigned int v2 : 5;
unsigned int v3 : 1;
unsigned int v4 : 8;
};
struct myBF b = { 3, 7, 0, 15 };
I may be misunderstanding your requirements entirely. Please comment if that's the case.
Update: Suppose you want to do this dynamically. Let's make a function that accepts an array of pairs, like in your example, and an output buffer:
/* Fill dst with bits.
* Returns one plus the number of bytes used or 0 on error.
*/
size_t bitstream(int (*arr)[2], size_t arrlen,
unsigned char * dst, size_t dstlen)
{
size_t total_bits = 0, bits_so_far = 0;
/* Check if there's enough space */
for (size_t i = 0; i != arrlen; ++i) { total_bits += arr[i][0]; }
if (dst == NULL || total_bits > CHAR_BIT * dstlen) { return 0; }
/* Set the output range to all zero */
memset(dst, 0, dstlen);
/* Populate the output range */
for (size_t i = 0; i != arrlen; ++i)
{
for (size_t bits_to_spend = arr[i][0], value = arr[i][1];
bits_to_spend != 0; /* no increment */ )
{
size_t const bit_offset = bits_so_far % CHAR_BIT;
size_t const byte_index = bits_so_far / CHAR_BIT;
size_t const cur_byte_capacity = CHAR_BIT - bit_offset;
/* Debug: Watch it work! */
printf("Need to store %zu, %zu bits to spend, capacity %zu.\n",
value, bits_to_spend, cur_byte_capacity);
dst[byte_index] |= (value << bit_offset);
if (cur_byte_capacity < bits_to_spend)
{
value >>= cur_byte_capacity;
bits_so_far += cur_byte_capacity;
bits_to_spend -= cur_byte_capacity;
}
else
{
bits_so_far += bits_to_spend;
bits_to_spend = 0;
}
}
}
return (bits_so_far + CHAR_BIT - 1) / CHAR_BIT;
}
Notes:
If the number arr[i][1] does not fit into arr[i][0] bits, only the residue modulo 2arr[i][0] is stored.
To be perfectly correct, the array type should be unsigned as well, otherwise the initialization size_t value = arr[i][1] may be undefined behaviour.
You can modify the error handling behaviour. For example, you could forgo transactionality and move the length check into the main loop. Also, instead of returning 0, you could return the numĀber of required bytes, so that the user can figure out how big the destination array needs to be (like snptrintf does).
Usage:
unsigned char dst[N];
size_t n = bitstream(array, sizeof array / sizeof *array, dst, sizeof dst);
for (size_t i = 0; i != n; ++i) { printf("0x%02X ", dst[n - i - 1]); }
For your example, this will produce 0x00 0xF0 0xE3, which is:
0x00 0xF0 0xE3
00000000 11110000 11100011
0000 00001111 0 000111 00011
padd 15 0 7 3
In standard C there's no way to access anything smaller than a char by any way other than the 'bitwise manipulation` you mention. I'm afraid you're out of luck, unless you come across a library somewhere out there that can help you.
I want to read in an int. For example 001. After I want to cut up the into so that A = 0, B = 0 and C = 1. I want to do this in C. Thanks!
If 001 is a bit representation of your integer value I, then:
int A = (I >> 2) & 0x1
int B = (I >> 1) & 0x1
int C = I & 0x1
You can achieve the result wanted by using modulus operator (%) and integer division (/). It's easier to understand than bitwise operators when you're starting to learn C.
scanf("%d", &i);
a = i / 100;
b = (i % 100) / 10;
c = (i % 100) % 10;
Building on Karl Bielefeldt's comment:
You can create a union of a char and a bitfield such as:
typedef union
{
unsigned char byte;
unsigned char b0 : 1;
unsigned char b1 : 1;
unsigned char b2 : 1;
unsigned char b3 : 1;
unsigned char b4 : 1;
unsigned char b5 : 1;
unsigned char b6 : 1;
unsigned char b7 : 1;
}TYPE_BYTE;
TYPE_BYTE sample_byte;
...then assign a value to sample_byte.byte and access each individual bit as sample_byte.b0, sample_byte.b1, etc. The order in which the bits are assigned is implementation dependent--read your compiler manual to see how it implements bitfields.
Bitfields can also be created with larger int types.
Edit (2011-03-15):
Assuming that maybe you want to read in a 3-digit base-10 integer and split the three digits into three variables, here's some code that should do that. It hasn't been tested so you might need to do some tweaking:
void split_base10(const unsigned int input, unsigned int *a, unsigned int *b, unsigned int *c)
{
unsigned int x = input;
*c = x%10;
x /= 10;
*b = x%10;
*a = x/10;
}
Good luck!
what i mean is that if i want to store for example 11110011 i want to store it in exactly 1 byte in memory not in array of chars.
example:
if i write 10001111 as an input while scanf is used it only get the first 1 and store it in the variable while what i want is to get the whole value into the variable of type char just to consume only one byte of memory.
One way to write that down would be something like this:
unsigned char b = 1 << 7 |
1 << 6 |
1 << 5 |
1 << 4 |
0 << 3 |
0 << 2 |
1 << 1 |
1 << 0;
Here's a snippet to read it from a string:
int i;
char num[8] = "11110011";
unsigned char result = 0;
for ( i = 0; i < 8; ++i )
result |= (num[i] == '1') << (7 - i);
like this....
unsigned char mybyte = 0xF3;
Using a "bit field"?
#include <stdio.h>
union u {
struct {
int a:1;
int b:1;
int c:1;
int d:1;
int e:1;
int f:1;
int g:1;
int h:1;
};
char ch;
};
int main()
{
union u info;
info.a = 1; // low-bit
info.b = 1;
info.c = 0;
info.d = 0;
info.e = 1;
info.f = 1;
info.g = 1;
info.h = 1; // high-bit
printf("%d %x\n", (int)(unsigned char)info.ch, (int)(unsigned char)info.ch);
}
You need to calculate the number and then just store it in a char.
If you know how binary works this should be easy for you. I dont know how you have the binary data stored, but if its in a string, you need to go through it and for each 1 add the appropriate power of two to a temp variable (initialized to zero at first). This will yield you the number after you go through the whole array.
Look here: http://www.gidnetwork.com/b-44.html
Use an unsigned char and then store the value in it. Simple?
If you have read it from a file and it is in the form of a string then something like this should work:
char str[] = "11110011";
unsigned char number = 0;
for(int i=7; i>=0; i--)
{
unsigned char temp = 1;
if (str[i] == '1')
{
temp <<= (7-i);
number |= temp;
}
}