1  /* numconv.c v1.0 - 2011-03-19
  2  The program asks you to enter a value whose first character indicates the format :
  3  d = decimal (base 10) h = hexadecimal (base 16), b = binary (base 2)
  4  It displays this value in decimal, hexadecimal, binary and sum of powers of 2 with spaces as separators :
  5  - Thousands to decimal values,
  6  - Bytes for hexadecimal values,
  7  - Quartets for binary values.
  8  Update: http://myc01.free.fr/numconverter
  9  
 10  License: Public Domain Dedication (CC0 1.0)
 11    http://creativecommons.org/publicdomain/zero/1.0/
 12  
 13  Usage: numconv.exe [bdh[value]]
 14    b : Binary value
 15    d : Decimal value
 16    h : Hexadecimal value
 17    value : Greater than or equal to 0.
 18  
 19  Examples:
 20    numconv.exe hFFAA
 21    numconv.exe b110011
 22    numconv.exe
 23  */
 24  
 25  #include <stdio.h>
 26  #include <string.h>
 27  
 28  
 29  void ClearSpaces (char *expression);
 30  unsigned int StringToInt (char *str, char format);
 31  void PrintDecimal (unsigned int value);
 32  void PrintHexa    (unsigned int value);
 33  void PrintBinary  (unsigned int value);
 34  void PrintP2      (unsigned int value);
 35  
 36  
 37  int main (int argc, char *argv[])
 38  {
 39    char str[256];
 40    char *str1;
 41    char format;
 42    unsigned int val;
 43  
 44    if (argc < 2)
 45    {
 46      printf ("Enter a value >=0 (d = decimal, hex = h, b = binary) :\n");
 47      gets (str);
 48      fflush (stdin);
 49      if (*str == '\0') return 0;
 50    }
 51    else
 52      strncpy (str, argv[1], 255);
 53  
 54    ClearSpaces (str);
 55  
 56    if (str[0] > 'a')
 57    {
 58      str1 = &str[1];
 59      format = str[0];
 60    }
 61    else
 62    {
 63      str1 = str;
 64      format = 'd';
 65    }
 66  
 67    val = StringToInt (str1, format);
 68  
 69    PrintDecimal (val);
 70    puts ("");
 71    PrintHexa (val);
 72    puts ("");
 73    PrintBinary (val);
 74    puts ("");
 75    PrintP2 (val);
 76  
 77    return 0;
 78  }  /* main */
 79  
 80  
 81  /* displays the result with a space as separator "thousands"
 82     example: d10 000 */
 83  void PrintDecimal (unsigned int value)
 84  {
 85    int i, size;
 86    char str[32];
 87  
 88    printf ("d");
 89  
 90    if (value < 1000)
 91      printf ("%u", value);
 92    else
 93    {
 94      sprintf (str, "%d", value);
 95      size = strlen (str);
 96      for (i = 0; i < size; i++)
 97      {
 98        if (((size - i) % 3) == 0)
 99          printf (" %c", str[i]);
100        else
101          printf ("%c", str[i]);
102      }
103    }
104  }  /* PrintDecimal */
105  
106  
107  /* displays the result with a space as separator "bytes"
108     example: hAA BB */
109  void PrintHexa (unsigned int value)
110  {
111    int i;
112    char str[32];
113  
114    printf ("h");
115  
116    if (value <= 0xFF)
117      printf ("%02X", value);
118    else
119    {
120      if (value > 0xFFFFFF) sprintf (str, "%08X", value); else
121      if (value > 0xFFFF  ) sprintf (str, "%06X", value); else
122      if (value > 0xFF    ) sprintf (str, "%04X", value);
123      for (i = 0; str[i] != '\0'; i++)
124      {
125        if (((i & 1) == 0) && (i > 1))
126          printf (" %c", str[i]);
127        else
128          printf ("%c", str[i]);
129      }
130    }
131  }  /* PrintHexa */
132  
133  
134  /* displays the result with a space as separator "bytes"
135     example: b0110 1011 */
136  void PrintBinary (unsigned int value)
137  {
138    int i, p, max_b;
139    char str[80];
140    unsigned int bit;
141    unsigned int mask = 1;
142  
143    for (i = 0, p = 31, max_b = 31; i < 32 ; ++i)
144    {
145      bit = (value & mask) >> i;
146      if (bit)
147      {
148        max_b = i;
149        str[p--] = '1';
150      }
151      else
152        str[p--] = '0';
153  	mask = mask << 1;
154    }
155    str[i] = '\0';
156  
157    max_b++;
158    if ((max_b % 4) != 0)
159      max_b = ((max_b >> 2) << 2) + 4;
160    else
161      max_b = ((max_b >> 2) << 2);
162    max_b = 32 - max_b;
163  
164    printf ("b");
165  
166    for (i = max_b; str[i] != '\0'; i++)
167    {
168      if (((i % 4) == 0) && (i > max_b))
169        printf (" %c", str[i]);
170      else
171        printf ("%c", str[i]);
172    }
173  }  /* PrintBinary */
174  
175  
176  /* displays the result as a sum of power of 2
177     example: =128 + 32 + 4 + 1 */
178  void PrintP2 (unsigned int value)
179  {
180    int i, min_b = 0;
181    unsigned bit;
182    unsigned mask = 1 << 31;
183  
184    printf ("=");
185  
186    for (i = 31; i >= 0 ; i--)
187    {
188      bit = (value & mask) >> i;
189      if (bit)
190      {
191        if (min_b++ > 0)
192          printf (" + %d", mask);
193        else
194          printf ("%d", mask);
195      }
196  	mask = mask >> 1;
197    }
198  
199    printf ("\n=");
200  
201    for (i = 31, mask = 1 << 31, min_b = 0; i >= 0 ; i--)
202    {
203      bit = (value & mask) >> i;
204      if (bit)
205      {
206        if (min_b++ > 0)
207          printf (" + 2^%d", i);
208        else
209          printf ("2^%d", i);
210      }
211  	mask = mask >> 1;
212    }
213  }  /* PrintP2 */
214  
215  
216  unsigned int StringToInt (char *str, char format)
217  {
218    unsigned int result, p;
219    int i;
220  
221    if (format == 'd')
222    {
223      if (sscanf (str, "%u", &result) == 1)
224        return result;
225      else
226        return 0;
227    }
228  
229    if (format == 'h')
230    {
231      if (sscanf (str, "%x", &result) == 1)
232        return result;
233      else
234        return 0;
235    }
236  
237    if (format == 'b')
238    {
239      for (i = strlen (str) - 1, result = 0, p = 1; i >= 0; i--)
240      {
241        if (str[i] == '1')
242          result = result + p;
243        else
244          if (str[i] != '0')
245            return 0;
246        p = p << 1;
247      }
248      return result;
249    }
250  
251    return 0;
252  }  /* StringToInt */
253  
254  
255  void ClearSpaces (char *expression)
256  {
257    int i, p = 0;
258    char c;
259    if ( expression == NULL) return;
260    if (*expression == '\0') return;
261  
262    for (i = 0; (c = expression[i]) != '\0'; i++)
263    {
264      if ((c != ' ') && (c != '\t') && (c != '\n') && (c != '\r'))
265        expression[p++] = c;
266    }
267    if (p != i) expression[p] = '\0';
268  }  /* ClearSpaces */