Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #167560

Re: Beginner....Decimal/Octal converter help

From Tim Rentsch <tr.17687@z991.linuxsc.com>
Newsgroups comp.lang.c
Subject Re: Beginner....Decimal/Octal converter help
Date 2022-09-09 09:16 -0700
Organization A noiseless patient Spider
Message-ID <86leqsr091.fsf@linuxsc.com> (permalink)
References <8ffd982c-2e82-4caa-9256-ec17be2efe56n@googlegroups.com>

Show all headers | View raw


ManyBeers <markzuffi@yahoo.com> writes:

> Hello I am teaching myself C and I need some help with a problem.
> After a search for dec/oct convert I found this code:
>
> [..code..]

I would like to offer a different kind of answer to your
questions.  First a suggestion:  for this kind of problem I think
you will find it helpful to use unsigned types exclusively.  In
the code below we will need (besides a plain 'unsigned' here and
there) two types, one for 8-bit values and one for 32-bit values:

  typedef unsigned char  UC;
  typedef unsigned int   UI;

Next we need to talk about what you're doing, which is base
conversion.  That is to say, you have a number in one base, and
you want to convert it to a different base.  Properly speaking
the word digit usually means a decimal digit, or a value between
0 and 9 inclusive.  However, we are working in various bases, so
I will use "digit" to mean a value in the appropriate range for
the base in question.  Now, what is a number in base B?  It is a
sequence of "digits" in base B, that is, values between 0 and
B-1.  A natural way to represent a number in base B is as an
array of elements for the "digits", where each element can hold a
value in the relevant range.  For bases up to 256, these elements
can be of type UC - an unsigned character can hold all values
between 0 and 255, so it can hold all values between 0 and 9 (for
decimal), or all values between 0 and 7 (for octal), or all
values between 0 and 15 (for hexadecimal), etc.  Here are some
sample holders of numbers in different bases:

  UC decimal_197[] = { 1, 9, 7 };
  UC octal_1777[]  = { 1, 7, 7, 7 };
  UC hex_FF[] = { 15, 15 };

(Slight digression:  Notice that there is nothing marking the
"end" of a number.  To use these variables we need to know how
many "digits" are held, which is the same as the number of
elements in each array.  There is a well-known idiom in C that
computes what this is, given the variable name.  That idiom is
typically written as a macro, as for example

  #define NUMBER_OF( a )    (sizeof (a) / sizeof *(a))

We will see uses of this macro in the code below.)

Okay, so we have some array variables holding numbers in
different bases.  To make use of these numbers we need to convert
them into C's native numeric type, which here means the type UI.
What is a value of type UI?  Because a UI has 32 bits, a variable
of type UI is a single "digit" in base 2**32, or 4294967296.
Here is a function to convert a base-10 number to a UI, which is
to say to a base-4294967296 number:

  UI
  base_10_to_base_4294967296( UC digits[], unsigned n ){
    unsigned i;
    UI r = 0;
    for(  i = 0;  i < n;  i++  ){
        r = r * 10 + digits[i];
    }
    return  r;
  }

Code to convert a base-8 number to a UI is almost identical:

  UI
  base_8_to_base_4294967296( UC digits[], unsigned n ){
    unsigned i;
    UI r = 0;
    for(  i = 0;  i < n;  i++  ){
        r = r * 8 + digits[i];
    }
    return  r;
  }

And it's easy to see how to generalize these functions into a
single function that will handle any base between 2 and 256:

  UI
  base_b_to_base_4294967296( unsigned b, UC digits[], unsigned n ){
    unsigned i;
    UI r = 0;
    for(  i = 0;  i < n;  i++  ){
        r = r * b + digits[i];
    }
    return  r;
  }

Having written these, we are now ready to write a simple test
driver:

  #include <stdio.h>

  #define NUMBER_OF( a )    (sizeof (a) / sizeof *(a))

  int
  main(){
    UC decimal_197[] = { 1, 9, 7 };
    UC octal_1777[]  = { 1, 7, 7, 7 };
    UC hex_FF[] = { 15, 15 };

    unsigned  decimal_197_digits = NUMBER_OF( decimal_197 );
    unsigned  octal_1777_digits  = NUMBER_OF( octal_1777 );
    unsigned  hex_FF_digits      = NUMBER_OF( hex_FF );

    UI u197d  = base_10_to_base_4294967296( decimal_197, decimal_197_digits );
    UI u1777o =  base_8_to_base_4294967296( octal_1777,  octal_1777_digits );
    UI uFFh   =  base_b_to_base_4294967296( 16, hex_FF,  hex_FF_digits );

    printf( " u197d is %7u  decimal\n", u197d );
    printf( "u1777o is %7u  decimal\n", u1777o );
    printf( "  uFFh is %7u  decimal\n", uFFh );
    printf( "\n" );

    printf( " u197d is %7o  octal\n", u197d );
    printf( "u1777o is %7o  octal\n", u1777o );
    printf( "  uFFh is %7o  octal\n", uFFh );
    printf( "\n" );

    printf( " u197d is %7x  hexidecimal\n", u197d );
    printf( "u1777o is %7x  hexidecimal\n", u1777o );
    printf( "  uFFh is %7x  hexidecimal\n", uFFh );
    printf( "\n" );

    return  0;
  }

Notice that the UI variables are not inherently either decimal,
octal, or hexadecimal.  The printed values come out as decimal,
octal, or hexadecimal, by virtue of what conversion specifier
(u, o, or x) is used in the printf() format string.  You see
that?

Now for the next step.  The code above allows conversion from an
arbitrary base (up to 256) to the base of C's native unsigned
type.  What we're looking for is a function that goes the other
direction:  from the base of C's native unsigned type to an array
of "digits" in a smaller base.  This function needs different
interface.  In particular, it should take a parameter that is a
pointer to an array of UC, and should return a count of the
number of digits in the result.  Here is our first try:

  unsigned
  base_4294967296_to_base_b_X( UI value, unsigned b, UC out[] ){
    UI v = value;
    unsigned k = 0;

    do {
      out[k] = v % b;
      k++;
    } while(  v /= b,  v != 0  );

    return  k;
  }

This function sort of works, but it has a problem:  the generated
"digits" are backwards!  An annoying artifact of conversions like
this is they really want to start at "the wrong end".

There are various ways to correct this problem, but probably the
easiest to explain is to put digits into a temporary array, and
then copy them in reverse order to the out[] array.  And so,

  unsigned
  base_4294967296_to_base_b( UI value, unsigned b, UC out[] ){
    UI v = value;
    unsigned k = 0;
    UC digits[100];
    unsigned i;

    do {
      digits[k] = v % b;
      k++;
    } while(  v /= b,  v != 0  );

    for(  i = 0;  i < k;  i++  ){
      out[ i ] = digits[ k-1-i ];
    }

    return  k;
  }

Please take a look over the above code and explanations, and see
if things make more sense now.  Are there any questions you have?

One more note, on a more advanced topic.  In the code above we
have limited the base-4294967296 numbers to only one UI, which is
to say limited those numbers to only one "digit".  If we want to
represent very large numbers, we can have an _array_ of UI, with
each element of the array holding a single base-4294967296 digit.
Doing that is possible of course, but it's a lot harder, so while
you're still learning C you might want to stick with the simpler
cases explained above.

Back to comp.lang.c | Previous | NextPrevious in thread | Next in thread | Find similar | Unroll thread


Thread

Beginner....Decimal/Octal converter help ManyBeers <markzuffi@yahoo.com> - 2022-09-08 11:34 -0700
  Re: Beginner....Decimal/Octal converter help Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2022-09-08 11:56 -0700
  Re: Beginner....Decimal/Octal converter help Ben Bacarisse <ben.usenet@bsb.me.uk> - 2022-09-08 20:19 +0100
  Re: Beginner....Decimal/Octal converter help Barry Schwarz <schwarzb@delq.com> - 2022-09-08 12:34 -0700
  Re: Beginner....Decimal/Octal converter help Joe Pfeiffer <pfeiffer@cs.nmsu.edu> - 2022-09-08 20:38 -0600
  Re: Beginner....Decimal/Octal converter help Öö Tiib <ootiib@hot.ee> - 2022-09-09 03:22 -0700
    Re: Beginner....Decimal/Octal converter help gazelle@shell.xmission.com (Kenny McCormack) - 2022-09-09 13:30 +0000
  Re: Beginner....Decimal/Octal converter help Tim Rentsch <tr.17687@z991.linuxsc.com> - 2022-09-09 09:16 -0700
    Re: Beginner....Decimal/Octal converter help scott@slp53.sl.home (Scott Lurndal) - 2022-09-09 19:06 +0000
      Re: Beginner....Decimal/Octal converter help David Brown <david.brown@hesbynett.no> - 2022-09-10 11:58 +0200
        Re: Beginner....Decimal/Octal converter help Bart <bc@freeuk.com> - 2022-09-10 11:37 +0100
          Re: Beginner....Decimal/Octal converter help David Brown <david.brown@hesbynett.no> - 2022-09-10 13:05 +0200
          Re: Beginner....Decimal/Octal converter help scott@slp53.sl.home (Scott Lurndal) - 2022-09-10 14:42 +0000
            Re: Beginner....Decimal/Octal converter help Bart <bc@freeuk.com> - 2022-09-10 16:10 +0100
              Re: Beginner....Decimal/Octal converter help David Brown <david.brown@hesbynett.no> - 2022-09-10 18:14 +0200
        Re: Beginner....Decimal/Octal converter help Ben Bacarisse <ben.usenet@bsb.me.uk> - 2022-09-10 12:54 +0100
          Re: Beginner....Decimal/Octal converter help David Brown <david.brown@hesbynett.no> - 2022-09-10 16:22 +0200
            Re: Beginner....Decimal/Octal converter help Ben Bacarisse <ben.usenet@bsb.me.uk> - 2022-09-10 19:03 +0100
              Re: Beginner....Decimal/Octal converter help Bart <bc@freeuk.com> - 2022-09-10 19:30 +0100
                Re: Beginner....Decimal/Octal converter help Ben Bacarisse <ben.usenet@bsb.me.uk> - 2022-09-10 19:47 +0100
                Re: Beginner....Decimal/Octal converter help David Brown <david.brown@hesbynett.no> - 2022-09-11 14:07 +0200
                Re: Beginner....Decimal/Octal converter help Ben Bacarisse <ben.usenet@bsb.me.uk> - 2022-09-11 16:12 +0100
                Re: Beginner....Decimal/Octal converter help David Brown <david.brown@hesbynett.no> - 2022-09-11 17:58 +0200
                Re: Beginner....Decimal/Octal converter help Ben Bacarisse <ben.usenet@bsb.me.uk> - 2022-09-11 21:14 +0100
                Re: Beginner....Decimal/Octal converter help Tim Rentsch <tr.17687@z991.linuxsc.com> - 2022-09-11 20:01 -0700
                Re: Beginner....Decimal/Octal converter help Richard Damon <Richard@Damon-Family.org> - 2022-09-11 23:32 -0400
                Re: Beginner....Decimal/Octal converter help scott@slp53.sl.home (Scott Lurndal) - 2022-09-12 13:52 +0000
                Re: Beginner....Decimal/Octal converter help Tim Rentsch <tr.17687@z991.linuxsc.com> - 2022-09-14 03:24 -0700
                Re: Beginner....Decimal/Octal converter help Richard Damon <Richard@Damon-Family.org> - 2022-09-14 08:10 -0400
                Re: Beginner....Decimal/Octal converter help Tim Rentsch <tr.17687@z991.linuxsc.com> - 2022-12-26 06:09 -0800
                Re: Beginner....Decimal/Octal converter help David Brown <david.brown@hesbynett.no> - 2022-09-12 16:53 +0200
                Re: Beginner....Decimal/Octal converter help Ben Bacarisse <ben.usenet@bsb.me.uk> - 2022-09-12 16:48 +0100
                Re: Beginner....Decimal/Octal converter help Bart <bc@freeuk.com> - 2022-09-12 17:46 +0100
                Re: Beginner....Decimal/Octal converter help Ben Bacarisse <ben.usenet@bsb.me.uk> - 2022-09-12 20:37 +0100
                Re: Beginner....Decimal/Octal converter help Bart <bc@freeuk.com> - 2022-09-13 00:03 +0100
                Re: Beginner....Decimal/Octal converter help David Brown <david.brown@hesbynett.no> - 2022-09-13 12:31 +0200
                Re: Beginner....Decimal/Octal converter help Ben Bacarisse <ben.usenet@bsb.me.uk> - 2022-09-13 12:48 +0100
                Re: Beginner....Decimal/Octal converter help Bart <bc@freeuk.com> - 2022-09-13 14:18 +0100
                Re: Beginner....Decimal/Octal converter help Anton Shepelev <anton.txt@g{oogle}mail.com> - 2022-09-13 17:13 +0300
                Re: Beginner....Decimal/Octal converter help Ben Bacarisse <ben.usenet@bsb.me.uk> - 2022-09-13 16:50 +0100
                Re: Beginner....Decimal/Octal converter help Bart <bc@freeuk.com> - 2022-09-13 18:47 +0100
                Re: Beginner....Decimal/Octal converter help Ben Bacarisse <ben.usenet@bsb.me.uk> - 2022-09-14 03:16 +0100
                Re: Beginner....Decimal/Octal converter help David Brown <david.brown@hesbynett.no> - 2022-09-13 20:15 +0200
                Re: Beginner....Decimal/Octal converter help Kaz Kylheku <480-992-1380@kylheku.com> - 2022-09-13 20:29 +0000
                Re: Beginner....Decimal/Octal converter help Bart <bc@freeuk.com> - 2022-09-13 22:22 +0100
                Re: Beginner....Decimal/Octal converter help Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2022-09-13 14:37 -0700
                Re: Beginner....Decimal/Octal converter help Bart <bc@freeuk.com> - 2022-09-13 23:16 +0100
                Re: Beginner....Decimal/Octal converter help scott@slp53.sl.home (Scott Lurndal) - 2022-09-13 22:16 +0000
                Re: Beginner....Decimal/Octal converter help Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2022-09-13 16:15 -0700
                Re: Beginner....Decimal/Octal converter help Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2022-09-13 16:15 -0700
                Re: Beginner....Decimal/Octal converter help Bart <bc@freeuk.com> - 2022-09-14 10:58 +0100
                Re: Beginner....Decimal/Octal converter help Ben Bacarisse <ben.usenet@bsb.me.uk> - 2022-09-14 15:36 +0100
                Re: Beginner....Decimal/Octal converter help Richard Harnden <richard.nospam@gmail.com> - 2022-09-14 21:53 +0100
                Re: Beginner....Decimal/Octal converter help Kaz Kylheku <480-992-1380@kylheku.com> - 2022-09-14 05:55 +0000
                Re: Beginner....Decimal/Octal converter help David Brown <david.brown@hesbynett.no> - 2022-09-14 10:10 +0200
                Re: Beginner....Decimal/Octal converter help Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2022-09-14 07:54 -0700
                Re: Beginner....Decimal/Octal converter help David Brown <david.brown@hesbynett.no> - 2022-09-14 18:32 +0200
                Re: Beginner....Decimal/Octal converter help Bart <bc@freeuk.com> - 2022-09-14 18:39 +0100
                Re: Beginner....Decimal/Octal converter help Kaz Kylheku <480-992-1380@kylheku.com> - 2022-09-15 01:12 +0000
                Re: Beginner....Decimal/Octal converter help David Brown <david.brown@hesbynett.no> - 2022-09-15 09:11 +0200
                Re: Beginner....Decimal/Octal converter help Tim Rentsch <tr.17687@z991.linuxsc.com> - 2022-09-15 08:07 -0700
                Re: Beginner....Decimal/Octal converter help Kaz Kylheku <480-992-1380@kylheku.com> - 2022-09-14 18:40 +0000
                Re: Beginner....Decimal/Octal converter help Kaz Kylheku <480-992-1380@kylheku.com> - 2022-09-14 05:45 +0000
                Re: Beginner....Decimal/Octal converter help Ben Bacarisse <ben.usenet@bsb.me.uk> - 2022-09-14 12:11 +0100
                Re: Beginner....Decimal/Octal converter help David Brown <david.brown@hesbynett.no> - 2022-09-14 09:57 +0200
                Re: Beginner....Decimal/Octal converter help Ben Bacarisse <ben.usenet@bsb.me.uk> - 2022-09-14 03:09 +0100
                Re: Beginner....Decimal/Octal converter help David Brown <david.brown@hesbynett.no> - 2022-09-14 10:29 +0200
                Re: Beginner....Decimal/Octal converter help Ben Bacarisse <ben.usenet@bsb.me.uk> - 2022-09-14 15:14 +0100
                Re: Beginner....Decimal/Octal converter help Tim Rentsch <tr.17687@z991.linuxsc.com> - 2022-09-14 07:36 -0700
                Re: Beginner....Decimal/Octal converter help Öö Tiib <ootiib@hot.ee> - 2022-10-03 01:10 -0700
                Re: Beginner....Decimal/Octal converter help Ben Bacarisse <ben.usenet@bsb.me.uk> - 2022-10-03 11:36 +0100
                Re: Beginner....Decimal/Octal converter help Öö Tiib <ootiib@hot.ee> - 2022-10-04 02:13 -0700
                Re: Beginner....Decimal/Octal converter help Ben Bacarisse <ben.usenet@bsb.me.uk> - 2022-10-04 16:27 +0100
                Re: Beginner....Decimal/Octal converter help Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2022-09-13 11:48 -0700
                Re: Beginner....Decimal/Octal converter help David Brown <david.brown@hesbynett.no> - 2022-09-14 10:38 +0200
                Re: Beginner....Decimal/Octal converter help scott@slp53.sl.home (Scott Lurndal) - 2022-09-14 14:27 +0000
                Re: Beginner....Decimal/Octal converter help Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2022-09-14 07:58 -0700
                Re: Beginner....Decimal/Octal converter help Tim Rentsch <tr.17687@z991.linuxsc.com> - 2022-09-16 13:06 -0700
                Re: Beginner....Decimal/Octal converter help Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2022-09-16 13:16 -0700
                Re: Beginner....Decimal/Octal converter help scott@slp53.sl.home (Scott Lurndal) - 2022-09-12 17:55 +0000
                Re: Beginner....Decimal/Octal converter help Kaz Kylheku <480-992-1380@kylheku.com> - 2022-09-12 18:22 +0000
                Re: Beginner....Decimal/Octal converter help Ben Bacarisse <ben.usenet@bsb.me.uk> - 2022-09-12 20:41 +0100
                Re: Beginner....Decimal/Octal converter help Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2022-09-11 15:45 -0700
                Re: Beginner....Decimal/Octal converter help Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2022-09-11 15:41 -0700
                Re: Beginner....Decimal/Octal converter help David Brown <david.brown@hesbynett.no> - 2022-09-12 17:06 +0200
              Re: Beginner....Decimal/Octal converter help Tim Rentsch <tr.17687@z991.linuxsc.com> - 2022-09-11 06:46 -0700
          Re: Beginner....Decimal/Octal converter help Tim Rentsch <tr.17687@z991.linuxsc.com> - 2022-09-11 06:57 -0700
      Re: Beginner....Decimal/Octal converter help Tim Rentsch <tr.17687@z991.linuxsc.com> - 2022-09-11 07:07 -0700
        Neologism (Was: Beginner....Decimal/Octal converter help) gazelle@shell.xmission.com (Kenny McCormack) - 2022-09-11 14:18 +0000
        Re: Beginner....Decimal/Octal converter help scott@slp53.sl.home (Scott Lurndal) - 2022-09-11 16:33 +0000
          Re: Beginner....Decimal/Octal converter help Tim Rentsch <tr.17687@z991.linuxsc.com> - 2022-09-13 15:40 -0700
  Re: Beginner....Decimal/Octal converter help scott@slp53.sl.home (Scott Lurndal) - 2022-09-09 23:08 +0000
    Re: Beginner....Decimal/Octal converter help Tim Rentsch <tr.17687@z991.linuxsc.com> - 2022-09-11 06:37 -0700
      Re: Beginner....Decimal/Octal converter help scott@slp53.sl.home (Scott Lurndal) - 2022-09-11 16:31 +0000
        Re: Beginner....Decimal/Octal converter help Tim Rentsch <tr.17687@z991.linuxsc.com> - 2022-09-13 15:44 -0700

csiph-web