Behind the data types 'char', 'int', 'float' et al, are varying sizes of storage space.  The 'bit' is the smallest data representation, and it is boolean;  i.e., it is either '0' or '1'.   'False' or 'True'.   'Off' or 'On'.  In this installment, we dig deep into the world of 'bits', 'nibbles' (groups of 4 'bits'), and 'bytes' (groups of 8 'bits' or 2 'nibbles').

 

(right-click to download)

/* pgm24 source */

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

#define MAX_32_BIT_NUM               4294967295
#define MAX_POWER_OF_2_NUM  2147483648

enum handlenewlines {HEADINGYES, HEADINGNO, FALSE = -1, TRUE};

char  *return_nibble(int);
void   prnt_data(unsigned int, int);
void   construct_32_bits_string(unsigned int, char *);
int      cvrt_hexval_char_to_int(int);

int main(int argc, char *argv[])  {
     int dobitpos;
     unsigned int numval;

     if ((argc == 2) && (strcmp(argv[1], "bitpos") == 0))
          dobitpos = TRUE;
     else if (argc == 1)
          dobitpos = FALSE;
     else {
          printf("\n\nThis program only recognizes \"bitpos\" as a parameter.\n\n");
          return(-1);
          }

     numval = 0;
     printf("\n");

     printf("'0' is a \"bit\" '0000' is a \"nibble\"\n");
     printf("'0000 0000' is two nibbles, also called a \"byte\"\n");
     printf("8 \"nibbles\" (or 4 \"bytes\") make a 32-bit value\n");
     printf("This applies to 'int' - integer, but may differ by machine or OS\n\n");

     if (dobitpos == FALSE) {
          for (numval = 0; numval < 16; numval++)
               prnt_data(numval, (numval == 0) ? HEADINGYES : HEADINGNO);

          /* 4 arbitrary integer values, and a MAX category value */
          prnt_data(3028912, HEADINGNO);
          prnt_data(29901098, HEADINGNO);
          prnt_data(782971823, HEADINGNO);
          prnt_data(1982971823, HEADINGNO);
          prnt_data(MAX_32_BIT_NUM, HEADINGNO);
          }
     else {
          printf(" === Showing one BIT position ===\n");
          prnt_data(1, HEADINGYES);

          for (numval = 2; numval < MAX_POWER_OF_2_NUM; numval *= 2)
               prnt_data(numval, HEADINGNO);

          prnt_data(MAX_POWER_OF_2_NUM, HEADINGNO);
          }

     printf("\n");
     return(0);
     }

void prnt_data(unsigned int numval, int newline)   {
     char rbuffer[48];

     if (newline == HEADINGYES)
          printf("MSB                                 LSB = Number\n");

     construct_32_bits_string(numval, rbuffer);
     printf("%s   %-16u\n", rbuffer, numval);
     }

void construct_32_bits_string(unsigned int val, char *result_string) {
     char all_nibbles[9];
     char rn7[5];    char rn6[5]; char rn5[5];    char rn4[5];
     char rn3[5];    char rn2[5]; char rn1[5];    char rn0[5];
     int n7; int n6;     int n5;         int n4;
     int n3; int n2;     int n1;        int n0;

     snprintf(all_nibbles, 9, "%08x", val);

     n7 = cvrt_hexval_char_to_int(all_nibbles[0]);
     n6 = cvrt_hexval_char_to_int(all_nibbles[1]);
     n5 = cvrt_hexval_char_to_int(all_nibbles[2]);
     n4 = cvrt_hexval_char_to_int(all_nibbles[3]);
     n3 = cvrt_hexval_char_to_int(all_nibbles[4]);
     n2 = cvrt_hexval_char_to_int(all_nibbles[5]);
     n1 = cvrt_hexval_char_to_int(all_nibbles[6]);
     n0 = cvrt_hexval_char_to_int(all_nibbles[7]);

     strcpy(rn0, return_nibble(n0));    strcpy(rn1, return_nibble(n1));
     strcpy(rn2, return_nibble(n2));    strcpy(rn3, return_nibble(n3));
     strcpy(rn4, return_nibble(n4));    strcpy(rn5, return_nibble(n5));
     strcpy(rn6, return_nibble(n6));    strcpy(rn7, return_nibble(n7));

     snprintf(result_string, 48, "%s %s %s %s %s %s %s %s", rn7, rn6, rn5, rn4, rn3, rn2, rn1, rn0);
     }

char *return_nibble(int nibble_value) {
     static char *bytestrs[17] = {
          "0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111",
          "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111",
          "UNKN"
          };

     return(bytestrs[nibble_value]);
     }

/* decimal 48 - 57 translates to character '0' to '9' */
/* decimal 97 - 102 translates to character 'a' to 'f' */
/* thus, if 'achar' is a digit CHARACTER, achar - 48 */
/* translates to NUMERIC 0 to 9 */
/* if 'achar' is NOT a digit CHARACTER, achar - 87 */
/* translates to NUMERIC 10 to 15 */
/* we end up with chars '0' - 'f' translated to ints 0 - 15 */
int cvrt_hexval_char_to_int(int achar) {
     int retval;

     retval = (isdigit(achar) != 0) ? achar - 48 : achar - 87;
     if ((retval >= 0) && (retval < 16))
          return(retval);
     else {
          printf("\n\nUnexpected error.\n\n");
          return(-1);
          }
     }