If I understand the two parts to your question (1) confirm your bit setting for 5 - unsigned char values from a 40-element integer array of -1 & 1 values; and (2) output the binary representation for each of the 5 - unsigned char values, then that can be accomplished a number of ways. In order to set a bit in each unsigned char valued, you simply bitwise OR the current value with 1 left-shifted the appropriate amount to set the bit at issue. For example to set the 3rd-bit in unsigned char v = 0;, you simply set v |= 1<<2;
The several different approaches to set the bit for all 5 unsigned char elements could be done with a nested loop brute force approach:
/* brute force nested loop approach */
for (i = 0; i < szarr; i++)
for (j = 0; j < CHAR_BIT; j++)
if (buf[i * CHAR_BIT + j] == 1) arr[i] |= (1 << j);
(where szarr is sizeof *arr for your char arr[5] = {0}; array (or just 5, and where CHAR_BIT (limits.h) defines the number of bits in a char (generally 8))
An unrolled approach which has benefits in efficiency (though most current compilers will attempt an unrolled solution with aggressive optimization). It is better illustrative of the process taking place:
/* unrolled loop setting all bits in each unsigned char per loop */
for (i = 0; i < szbuf; i+=8) {
if (buf[ i ] == 1) arr[i/8] |= 1;
if (buf[i+1] == 1) arr[i/8] |= (1 << 1);
if (buf[i+2] == 1) arr[i/8] |= (1 << 2);
if (buf[i+3] == 1) arr[i/8] |= (1 << 3);
if (buf[i+4] == 1) arr[i/8] |= (1 << 4);
if (buf[i+5] == 1) arr[i/8] |= (1 << 5);
if (buf[i+6] == 1) arr[i/8] |= (1 << 6);
if (buf[i+7] == 1) arr[i/8] |= (1 << 7);
}
And finally how can you easily look at the binary representation of each of your unsigned values to confirm your logic. There are as many variations in how you can accomplish this as with anything else. For general testing, I find a simple function that returns a char * representation of the binary string, padded to a desired length, as, or more, useful than just about any of the other methods as it allow you to retain normal formatting control within a single printf, etc..
While not 100% necessary with unsigned values, as most hardware agrees that 4-bytes make up an int and unsigned. However, since there can be variations, it is a good idea to either use exact types or use simple preprocessor directives to determine the number of BITS_PER_LONG, etc.. With a generic binary print routine that will handle padding long unsigned values, a simple test is helpful between 32/64-bit machines. e.g.:
/* BITS_PER_LONG */
#if defined(__LP64__) || defined(_LP64)
# define BITS_PER_LONG 64
#else
# define BITS_PER_LONG 32
#endif
...
/** returns pointer to binary representation of 'v' zero padded to 'sz'.
* returns pointer to string contianing binary representation of
* unsigned 64-bit (or less ) value zero padded to 'sz' digits.
*/
char *binpad (const unsigned long v, const size_t sz)
{
static char s[BITS_PER_LONG + 1] = {0};
char *p = s + BITS_PER_LONG;
register size_t i;
for (i = 0; i < sz; i++)
*--p = (v>>i & 1) ? '1' : '0';
return p;
}
Now putting all the pieces together and making up a 40-element array of values that are -1 or 1 for testing purposes, you could do something like the following, and using the simple compiler definitions NESTED to signify to build with the brute force nested loop version, or with the unrolled version if no definitions are given:
#include <stdio.h>
/* CHAR_BIT */
#ifndef CHAR_BIT
# define CHAR_BIT 8
#endif
/* BITS_PER_LONG */
#if defined(__LP64__) || defined(_LP64)
# define BITS_PER_LONG 64
#else
# define BITS_PER_LONG 32
#endif
char *binpad (const unsigned long v, const size_t sz);
int main (void){
unsigned char buf[] = { -1, -1, 1, -1, -1, -1, 1, 1,
-1, 1, -1, -1, -1, 1, 1, -1,
1, -1, -1, -1, 1, 1, -1, -1,
-1, -1, -1, 1, 1, -1, -1, -1,
-1, -1, 1, 1, -1, -1, -1, 1 };
unsigned char arr[5] = {0};
unsigned i, szarr = (unsigned) sizeof arr;
#ifdef NESTED
unsigned j;
/* brute force nested loop approach */
for (i = 0; i < szarr; i++)
for (j = 0; j < CHAR_BIT; j++)
if (buf[i * CHAR_BIT + j] == 1) arr[i] |= (1 << j);
#else
unsigned szbuf = (unsigned) sizeof buf;
/* unrolled loop setting all bits in each unsigned char per loop */
for (i = 0; i < szbuf; i+=8) {
if (buf[ i ] == 1) arr[i/8] |= 1;
if (buf[i+1] == 1) arr[i/8] |= (1 << 1);
if (buf[i+2] == 1) arr[i/8] |= (1 << 2);
if (buf[i+3] == 1) arr[i/8] |= (1 << 3);
if (buf[i+4] == 1) arr[i/8] |= (1 << 4);
if (buf[i+5] == 1) arr[i/8] |= (1 << 5);
if (buf[i+6] == 1) arr[i/8] |= (1 << 6);
if (buf[i+7] == 1) arr[i/8] |= (1 << 7);
}
#endif
for (i = 0; i < szarr; i++) /* validate the bit settings */
printf (" arr[%2u] : %3u (%s)\n",
i, arr[i], binpad (arr[i], CHAR_BIT));
return 0;
}
/** returns pointer to binary representation of 'v' zero padded to 'sz'.
* returns pointer to string contianing binary representation of
* unsigned 64-bit (or less ) value zero padded to 'sz' digits.
*/
char *binpad (const unsigned long v, const size_t sz)
{
static char s[BITS_PER_LONG + 1] = {0};
char *p = s + BITS_PER_LONG;
register size_t i;
for (i = 0; i < sz; i++)
*--p = (v>>i & 1) ? '1' : '0';
return p;
}
Example Use/Output
The output values are for each of your 5 unsigned char array elements showing both the decimal value created from the interpretations of -1's and 1's as well as the binary representation for that number padded to 8-chars:
$ ./bin/array_uc_bits
arr[ 0] : 196 (11000100)
arr[ 1] : 98 (01100010)
arr[ 2] : 49 (00110001)
arr[ 3] : 24 (00011000)
arr[ 4] : 140 (10001100)
Look over all the answers and all the approaches and let me know if you have additional questions.
Note: if you are unfamiliar with how to set a label definition like NESTED at compile time, all you need do is pass it as an option preceded with -D, e.g. -DNESTED passed on the command line will trigger compiling the nested brute force code., e.g.
$ gcc -Wall -Wextra -Ofast -DNESTED -o bin/array_uc_bits_nest array_uc_bits.c
is all that is required. (of course adjust the input and output names to your liking.)
~0will not set the values to all-zero, but all one. 2) Don't use magic numbers. If you mean the size of the array, use thesizeofthe array! Be carful when bitshifting signed integers (you very well use them!).memset(array, ~0, 5);sets all the bits to1(probably). To set to 0 , use0instead of~0. Or preferably writeunsigned char chararray[5] = { 0 };