23 Apr 2012

Display HEX and Binary representation of an integer with C

a little example in C on how to display an integer in hex an binary:

/**
 * Name        : bitwise.c
 * Author      : wus
 * Version     : $Id: bitwise.c 13 2012-04-23 15:37:41Z wus $
 * Copyright   : GPL
 * Description : Print an 8-64 bit integer in hex and binary to stdout.
 *
 * NOTE: gcc needs the -lm option enabled to include the math library (must add
 *       -lm after the source file, WTF?)
 * NOTE: compile flags: $ gcc -ofilename filename.c -lm
 */

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <math.h>

int int_size = 64;  // num bits of integer

void usage(void) {
 printf("Usage: bitwise <%d bit int>\n\n", int_size);
 printf("Exit codes:\n");
 printf("  2 argument error\n");
 printf("  3 overflow error\n");
}

char dec2hex(int digit) {
 if (digit < 10) return (digit + 48);
 switch(digit) {
  case 10: return 'A';
  case 11: return 'B';
  case 12: return 'C';
  case 13: return 'D';
  case 14: return 'E';
  case 15: return 'F';
 }
 return '*';
}

/**
 * generate binary and hex string from an integer
 *
 * loop bit for bit (MSB) over an integer, generate binary and hex string
 *
 * param num:      the number
 * param result:   max. 64 bits + 7 spaces (pairs by 4 and an ending \0
 * param hex:      hex representation, 8 digits and one \0
 * param int_size: number of bits to represent in the output
 */
void format_bin(uint64_t num, char result[78], char hex[9], int int_size) {

 int pos_bit, pos_string = 0;
 int pos_hex = int_size / 4 - 1;
 int str_size = int_size + (int_size/4 - 1);
 hex[pos_hex] = 0;

 for(pos_bit=0; pos_bit < int_size; pos_bit++, pos_string++) {
  // add spaces
  if (pos_bit % 4 == 0 && pos_bit != 0) {
   result[str_size - 1 - pos_string++] = ' ';
  }

  // check if current bit is set
  int t = ((num & (1L<<pos_bit)) ? 1 : 0);
  result[str_size - 1 - pos_string] = t + 48;
  
  // handle hex
  int pot = pos_bit % 4;

  if (t) {
   switch (pot) {
    case 0: hex[pos_hex] += 1; break;
    case 1: hex[pos_hex] += 2; break;
    case 2: hex[pos_hex] += 4; break;
    case 3: hex[pos_hex] += 8; break;
   }
  }

  // next character
  if (pot == 3) {
   // make sure the int is a character and store it in the
   // result hex string
   hex[pos_hex] = dec2hex(hex[pos_hex]);
   hex[--pos_hex] = 0;
  }
 } // end for loop

 hex[int_size/4] = '\0';
 result[str_size] = '\0';
}

/**
 * generate binary and hex representation of an integer value
 */
int main(int argc, char* argv[]) {

 if (argc != 2) {
  usage();
  exit(2);  
 }

 int arg1 = atoi(argv[1]);
 // check overflow
 if (arg1 > (pow(2, int_size) - 1)) {
  printf("Overflow detected, we can handle max. %d bit integers!\n\n",
         int_size);
  usage();
  exit(3);
 }
 uint8_t input = arg1;
 
 char str[78];
 char hex[9];
 format_bin(input, str, hex, int_size);
 printf("\n0x%s - %s\n", hex, str);

 return EXIT_SUCCESS;
}