Since I'm an avid C hobbyist (and I have the day off work) I thought I'd tackle the "bits and nibbles" problem with a simple conversion program. There are some things about it that I suspect are wrong -- ie, I can see that converting with atoi() rather than atol() gives me a different result with very large or negative numbers, and I'm not sure which gives the more appropriate result in all cases. I've looked at strtoul(), though I have to admit the man page made my eyes cross a bit -- is this what I need? I'm afraid that as much as I enjoy coding, math is not my strongest point
Suggestions, feedback, and guidance are welcome ...
Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
/* cvtbin.c - a simple calculator for binary to decimal
* and decimal to binary conversion */
#define UNIX 1
#if UNIX
# define CLEAR_SCREEN "clear"
#else
# define CLEAR_SCREEN "clr"
#endif
int c[32]; char s[40];
char *
itob (unsigned long int n)
{
int i, j, k = 0; char *p;
for (i = 0; i < 32; i++)
c[i] = (n >> i) & 0x1;
for (i = 0, j = 31; j >= 0; i++, j--)
{
if (k == 4)
{
k = 0;
s[i++] = ' ';
}
s[i] = c[j]+'0'; k++;
}
if ((p = strchr (s, '1')) == NULL)
return s+35;
k = p - s;
k /= 5; k *= 5;
return s+k;
}
unsigned long int
btoi (char *sb)
{
int i, j; unsigned long int n;
size_t k = strlen (sb)-1;
for (i = 0, j = k; j >= 0; i++, j--)
{
if (sb[j] > '1')
return 0;
if (sb[j] != ' ')
c[i] = sb[j]-'0';
}
i = k+1; n = 0;
while (i--)
{
n <<= 1;
n += c[i];
}
return n;
}
void
clr_stdin (char *s)
{
char ch, *p;
if ((p = strchr (s, '\n')) == NULL)
while ((ch = getchar()) != '\n' && ch != EOF)
;
else *p = '\0';
}
void
to_binary (void)
{
char in[10+1]; unsigned long int n;
system (CLEAR_SCREEN);
while (1)
{
printf ("Enter a number to convert to binary > ");
if (fgets (in, 10+1, stdin))
{
if (*in == '\n' || (isdigit (*in) == 0 && *in != '-'))
break;
clr_stdin (in);
n = atol (in);
printf ("\ndecimal %lu is binary %s\n\n", n, itob (n));
}
}
}
void
to_decimal (void)
{
char in[39+1]; unsigned long int t;
system (CLEAR_SCREEN);
while (1)
{
printf ("Enter a binary string to convert to decimal\n> ");
if (fgets (in, 39+1, stdin))
{
if (*in == '\n' || isdigit (*in) == 0)
break;
clr_stdin (in);
t = btoi (in);
printf ("\nbinary %s is decimal %lu", in, t);
if (t == 0)
printf (" or not binary");
printf ("\n\n");
}
}
}
int
main (void)
{
char in[2+1];
while (1)
{
system (CLEAR_SCREEN);
printf ("Enter your selection\n"
" 1) convert decimal to binary\n"
" 2) convert binary to decimal\n"
"or any other key to quit > ");
if (fgets (in, 2+1, stdin))
{
clr_stdin (in);
if (in[1])
break;
if (*in == '1')
to_binary();
else if (*in == '2')
to_decimal();
else break;
}
}
printf ("\nGood bye\n\n");
return 0;
}