Thread: binary decimal conversion

  1. #1
    old man
    Join Date
    Dec 2005
    Posts
    90

    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. #2
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    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.
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

  3. #3
    old man
    Join Date
    Dec 2005
    Posts
    90
    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 subscribe to a feed

Similar Threads

  1. Replies: 3
    Last Post: 07-04-2008, 12:39 PM
  2. Binary to Base 10 decimal conversion
    By JFonseka in forum C Programming
    Replies: 13
    Last Post: 11-20-2007, 04:14 PM
  3. Screwy Linker Error - VC2005
    By Tonto in forum C++ Programming
    Replies: 5
    Last Post: 06-19-2007, 02:39 PM
  4. Binary Search Trees Part III
    By Prelude in forum A Brief History of Cprogramming.com
    Replies: 16
    Last Post: 10-02-2004, 03:00 PM
  5. Decimal to binary conversion help needed
    By Unregistered in forum C Programming
    Replies: 6
    Last Post: 02-06-2002, 01:03 PM