# Thread: binary decimal conversion

1. ## binary decimal conversion

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;
}```

2. This stuff is a no-go for me.
Code:
```#if UNIX
# define CLEAR_SCREEN "clear"
#else
# define CLEAR_SCREEN "clr"
#endif```
System calls in general are not too popular with folks.

Globals may be frowned upon too.

The strtoul approach need not be as brutal as it may look.
Code:
```#include <stdio.h>
#include <stdlib.h>

int main(void)
{
char binary[] = "1101010110", *end;
unsigned long value = strtoul(binary, &end, 2);
if ( *end == '\0' )
{
printf("value = %lu\n", value);
}
return 0;
}

/* my output
value = 854
*/```
This seems a bit cryptic: anytime "magic numbers" pop up.
Code:
```  if ((p = strchr (s, '1')) == NULL)
return s+35;
k = p - s;
k /= 5;  k *= 5;
return s+k;```
If you changed an array size, for example changing s from a size of 40 to say 120, would a maintainer (even yourself) have enough hints to track down other places to update?

The 32-bit-centricity can be avoided.

But it looks like you're having fun, so I'll stop picking nits.

3. Thanks for your comments. It's true I get sloppy with globals -- that's a known bad habit of mine. And the part you call "cryptic" I knew was a horrible kludge ... I sort of winced when I coded it.

That strtoul() example you give is nice; I should've looked at that earlier since it's definitely a more practical way to convert a binary string.

Anyway, yes, I'm having fun, but the nits are good, too

Popular pages Recent additions