prints out an unsigned long in decimal

Discussion in 'C Programming' started by Matt, Sep 28, 2003.

  1. Matt

    Matt Guest

    Given only putchar (no sprintf, itoa, etc.) write a routine putlong
    that prints out an unsigned long in decimal. No array allowed.

    I have no idea if we can't use array to solve the problem.
     
    Matt, Sep 28, 2003
    #1
    1. Advertisements

  2. Matt <> scribbled the following:
    > Given only putchar (no sprintf, itoa, etc.) write a routine putlong
    > that prints out an unsigned long in decimal. No array allowed.


    > I have no idea if we can't use array to solve the problem.


    Hey come on. This problem is really quite easy. I'll leave you with a
    skeleton of the solution.

    void writeLong(unsigned long l) {
    putchar( /* what goes here? */ );
    if (l) {
    writeLong( /* what goes here? */ );
    }
    }

    I managed to solve the problem in a way similar to the above without
    using arrays, or indeed other variables than l, at all. No need for
    sprintf, itoa, etc either.

    --
    /-- Joona Palaste () ---------------------------\
    | Kingpriest of "The Flying Lemon Tree" G++ FR FW+ M- #108 D+ ADA N+++|
    | http://www.helsinki.fi/~palaste W++ B OP+ |
    \----------------------------------------- Finland rules! ------------/
    "Life without ostriches is like coffee with milk."
    - Mika P. Nieminen
     
    Joona I Palaste, Sep 28, 2003
    #2
    1. Advertisements

  3. "Matt" <> wrote in message
    news:...
    > Given only putchar (no sprintf, itoa, etc.) write a routine putlong
    > that prints out an unsigned long in decimal. No array allowed.
    >
    > I have no idea if we can't use array to solve the problem.


    One idea is to go with something like:
    unsigned long exp = 10;
    while(exp<val) exp*=10;
    while( exp/=10 ) putchar( '0'+(val/exp)%10 );

    Bug left in on purpose, and optimizations are possible.

    Cheers,
    Ivan
    --
    http://ivan.vecerina.com
     
    Ivan Vecerina, Sep 28, 2003
    #3
  4. "Ivan Vecerina" <ivecATmyrealboxDOTcom> wrote:

    > "Matt" <> wrote in message
    > news:...
    >> Given only putchar (no sprintf, itoa, etc.) write a routine putlong
    >> that prints out an unsigned long in decimal. No array allowed.
    >>
    >> I have no idea if we can't use array to solve the problem.

    >
    > One idea is to go with something like:
    > unsigned long exp = 10;
    > while(exp<val) exp*=10;
    > while( exp/=10 ) putchar( '0'+(val/exp)%10 );
    >
    > Bug left in on purpose, and optimizations are possible.


    Which bug? I count at least two.

    --
    Richard Heathfield :
    "Usenet is a strange place." - Dennis M Ritchie, 29 July 1999.
    C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
    K&R answers, C books, etc: http://users.powernet.co.uk/eton
     
    Richard Heathfield, Sep 28, 2003
    #4
  5. Matt

    Joe Wright Guest

    Matt wrote:
    >
    > Given only putchar (no sprintf, itoa, etc.) write a routine putlong
    > that prints out an unsigned long in decimal. No array allowed.
    >
    > I have no idea if we can't use array to solve the problem.


    Because it's an example program on page 64 or K&R2 which uses an array
    as temporary storage. The alogrithm to convert binary to 'decimal'
    generates digits, least significant first. Then the array is reversed
    (another example of how to reverse a string). They don't want you to
    copy the example from the book.

    You can do it without an array. Think recursion. Good luck.
    --
    Joe Wright mailto:
    "Everything should be made as simple as possible, but not simpler."
    --- Albert Einstein ---
     
    Joe Wright, Sep 29, 2003
    #5
  6. "Richard Heathfield" <> wrote in message
    news:bl7m4k$6i9$...
    > "Ivan Vecerina" <ivecATmyrealboxDOTcom> wrote:
    >
    > > "Matt" <> wrote in message
    > > news:...
    > >> Given only putchar (no sprintf, itoa, etc.) write a routine putlong
    > >> that prints out an unsigned long in decimal. No array allowed.
    > >>
    > >> I have no idea if we can't use array to solve the problem.

    > >
    > > One idea is to go with something like:
    > > unsigned long exp = 10;
    > > while(exp<val) exp*=10;
    > > while( exp/=10 ) putchar( '0'+(val/exp)%10 );
    > >
    > > Bug left in on purpose, and optimizations are possible.

    >
    > Which bug? I count at least two.


    shush! ;) Is a portability problem included in your count?

    Regards,
    Ivan
    --
    http://ivan.vecerina.com
     
    Ivan Vecerina, Sep 29, 2003
    #6
  7. "Ivan Vecerina" <ivecATmyrealboxDOTcom> wrote:

    >
    > "Richard Heathfield" <> wrote in message
    > news:bl7m4k$6i9$...
    >> "Ivan Vecerina" <ivecATmyrealboxDOTcom> wrote:
    >>
    >> > "Matt" <> wrote in message
    >> > news:...
    >> >> Given only putchar (no sprintf, itoa, etc.) write a routine putlong
    >> >> that prints out an unsigned long in decimal. No array allowed.
    >> >>
    >> >> I have no idea if we can't use array to solve the problem.
    >> >
    >> > One idea is to go with something like:
    >> > unsigned long exp = 10;
    >> > while(exp<val) exp*=10;
    >> > while( exp/=10 ) putchar( '0'+(val/exp)%10 );
    >> >
    >> > Bug left in on purpose, and optimizations are possible.

    >>
    >> Which bug? I count at least two.

    >
    > shush! ;) Is a portability problem included in your count?


    Well, the first is that it basically gives the wrong answer sometimes. The
    second is a namespace issue.

    --
    Richard Heathfield :
    "Usenet is a strange place." - Dennis M Ritchie, 29 July 1999.
    C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
    K&R answers, C books, etc: http://users.powernet.co.uk/eton
     
    Richard Heathfield, Sep 29, 2003
    #7
  8. "Richard Heathfield" <> wrote in message
    news:bl8hst$6rv$...
    | "Ivan Vecerina" <ivecATmyrealboxDOTcom> wrote:
    | > "Richard Heathfield" <> wrote in message
    | > news:bl7m4k$6i9$...
    | >> "Ivan Vecerina" <ivecATmyrealboxDOTcom> wrote:
    | >> > "Matt" <> wrote in message
    | >> > news:...
    | >> >> Given only putchar (no sprintf, itoa, etc.) write a routine putlong
    | >> >> that prints out an unsigned long in decimal. No array allowed.
    | >> >>
    | >> >> I have no idea if we can't use array to solve the problem.
    | >> >
    | >> > One idea is to go with something like:
    | >> > unsigned long exp = 10;
    | >> > while(exp<val) exp*=10;
    | >> > while( exp/=10 ) putchar( '0'+(val/exp)%10 );
    | >> >
    | >> > Bug left in on purpose, and optimizations are possible.
    | >>
    | >> Which bug? I count at least two.
    | >
    | > shush! ;) Is a portability problem included in your count?

    Hi Richard,

    | Well, the first is that it basically gives the wrong answer sometimes.
    Yes - a classic bounds problem I left for Matt to eventually find.

    | The second is a namespace issue.
    I am not sure what you mean by this. I assume you refer
    to C name spaces, and not C++ namespace-s.
    A conflict with the exp() function if using <math.h> ?


    What I though of as a portability problem was the '0'+....
    It could be replaced with "0123456789"[...],
    or ...["0123456789"] ;)


    Also, note that the code I posted in this thread is not
    a recommendation, just a hint at a possible approach.

    Regards,
    Ivan

    --
    http://ivan.vecerina.com
     
    Ivan Vecerina, Sep 29, 2003
    #8
  9. Matt

    Martijn Guest

    Ivan Vecerina wrote:
    >> The second is a namespace issue.

    > I am not sure what you mean by this. I assume you refer
    > to C name spaces, and not C++ namespace-s.
    > A conflict with the exp() function if using <math.h> ?


    That, plus val not being declared... :)

    --
    Martijn
    http://www.sereneconcepts.nl
     
    Martijn, Sep 29, 2003
    #9
  10. Matt

    pete Guest

    Ivan Vecerina wrote:

    > A conflict with the exp() function if using <math.h> ?


    How about regardless of whether or not using <math.h> ?

    --
    pete
     
    pete, Sep 29, 2003
    #10
  11. Matt

    CBFalconer Guest

    Richard Heathfield wrote:
    > "Ivan Vecerina" <ivecATmyrealboxDOTcom> wrote:
    > > "Richard Heathfield" wrote in message
    > >> "Ivan Vecerina" <ivecATmyrealboxDOTcom> wrote:
    > >> > "Matt" <> wrote in message
    > >> >
    > >> >> Given only putchar (no sprintf, itoa, etc.) write a routine
    > >> >> putlong that prints out an unsigned long in decimal. No
    > >> >> array allowed.
    > >> >>
    > >> >> I have no idea if we can't use array to solve the problem.
    > >> >
    > >> > One idea is to go with something like:
    > >> > unsigned long exp = 10;
    > >> > while(exp<val) exp*=10;
    > >> > while( exp/=10 ) putchar( '0'+(val/exp)%10 );
    > >> >
    > >> > Bug left in on purpose, and optimizations are possible.
    > >>
    > >> Which bug? I count at least two.

    > >
    > > shush! ;) Is a portability problem included in your count?

    >
    > Well, the first is that it basically gives the wrong answer
    > sometimes. The second is a namespace issue.


    How about (untested):

    unsigned long xp = 1;

    while ((val / xp) >= 10) xp *= 10;
    do {
    putchar('0' + (val/xp) % 10);
    } while (xp /= 10);

    which may be easier on resources than the recursive method.

    --
    Chuck F () ()
    Available for consulting/temporary embedded and systems.
    <http://cbfalconer.home.att.net> USE worldnet address!
     
    CBFalconer, Sep 29, 2003
    #11
  12. Matt

    Dan Pop Guest

    In <bl8hst$6rv$> Richard Heathfield <> writes:

    >"Ivan Vecerina" <ivecATmyrealboxDOTcom> wrote:
    >
    >>
    >> "Richard Heathfield" <> wrote in message
    >> news:bl7m4k$6i9$...
    >>> "Ivan Vecerina" <ivecATmyrealboxDOTcom> wrote:
    >>>
    >>> > "Matt" <> wrote in message
    >>> > news:...
    >>> >> Given only putchar (no sprintf, itoa, etc.) write a routine putlong
    >>> >> that prints out an unsigned long in decimal. No array allowed.
    >>> >>
    >>> >> I have no idea if we can't use array to solve the problem.
    >>> >
    >>> > One idea is to go with something like:
    >>> > unsigned long exp = 10;
    >>> > while(exp<val) exp*=10;
    >>> > while( exp/=10 ) putchar( '0'+(val/exp)%10 );
    >>> >
    >>> > Bug left in on purpose, and optimizations are possible.
    >>>
    >>> Which bug? I count at least two.

    >>
    >> shush! ;) Is a portability problem included in your count?

    >
    >Well, the first is that it basically gives the wrong answer sometimes. The
    >second is a namespace issue.


    No namespace issue, as long as exp has block scope.

    Dan
    --
    Dan Pop
    DESY Zeuthen, RZ group
    Email:
     
    Dan Pop, Sep 29, 2003
    #12
  13. Ivan Vecerina wrote:

    > "Richard Heathfield" <> wrote in message
    > news:bl8hst$6rv$...
    > | "Ivan Vecerina" <ivecATmyrealboxDOTcom> wrote:
    > | > "Richard Heathfield" <> wrote in message
    > | > news:bl7m4k$6i9$...
    > | >> "Ivan Vecerina" <ivecATmyrealboxDOTcom> wrote:
    > | >> > "Matt" <> wrote in message
    > | >> > news:...
    > | >> >> Given only putchar (no sprintf, itoa, etc.) write a routine
    > | >> >> putlong that prints out an unsigned long in decimal. No array
    > | >> >> allowed.
    > | >> >>
    > | >> >> I have no idea if we can't use array to solve the problem.
    > | >> >
    > | >> > One idea is to go with something like:
    > | >> > unsigned long exp = 10;
    > | >> > while(exp<val) exp*=10;
    > | >> > while( exp/=10 ) putchar( '0'+(val/exp)%10 );
    > | >> >
    > | >> > Bug left in on purpose, and optimizations are possible.
    > | >>
    > | >> Which bug? I count at least two.
    > | >
    > | > shush! ;) Is a portability problem included in your count?
    >
    > Hi Richard,
    >
    > | Well, the first is that it basically gives the wrong answer sometimes.
    > Yes - a classic bounds problem I left for Matt to eventually find.
    >
    > | The second is a namespace issue.
    > I am not sure what you mean by this. I assume you refer
    > to C name spaces, and not C++ namespace-s.
    > A conflict with the exp() function if using <math.h> ?


    Well, that's what I had in mind, yes, but see Dan Pop's rebuttal elsethread.

    > What I though of as a portability problem was the '0'+....


    No, that bit's fine, because '0' + (0 through 9) is guaranteed to give you
    '0' through '9'. The Standard says:

    "In both the source and execution basic character sets, the value of each
    character after 0 in the above list of decimal digits shall be one greater
    than the value of the previous."

    --
    Richard Heathfield :
    "Usenet is a strange place." - Dennis M Ritchie, 29 July 1999.
    C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
    K&R answers, C books, etc: http://users.powernet.co.uk/eton
     
    Richard Heathfield, Sep 29, 2003
    #13
  14. "Richard Heathfield" <> wrote in message
    news:bla0q3$1sk$...
    > Ivan Vecerina wrote:
    > > "Richard Heathfield" <> wrote in message
    > > news:bl8hst$6rv$...
    > > | The second is a namespace issue.
    > > I am not sure what you mean by this. I assume you refer
    > > to C name spaces, and not C++ namespace-s.
    > > A conflict with the exp() function if using <math.h> ?

    >
    > Well, that's what I had in mind, yes, but see Dan Pop's rebuttal

    elsethread.
    Yes, the name of a global function should not interfere with a local
    variable. (yes, for those who doubted of it, the 3 code lines are
    intended to be within the body of a function...).

    But things get nastier with the C99 standard: the standard <tgmath.h>
    header is intended to define a bunch of macros providing type-generic
    math functions -- kind of like C++ function overloads -- including
    an exp() macro.

    This said, if exp is a function-like macro (and it shall be IIUC),
    the code will still be ok even after the inclusion of <tgmath.h>:
    function-like macros are only substituted when they are
    followed by a '(' (std 6.10.3/10).

    Anyway, this goes beyond the scope of my initial post...

    > > What I though of as a portability problem was the '0'+....

    >
    > No, that bit's fine, because '0' + (0 through 9) is guaranteed to give you
    > '0' through '9'. The Standard says:
    >
    > "In both the source and execution basic character sets, the value of each
    > character after 0 in the above list of decimal digits shall be one greater
    > than the value of the previous."

    5.2.1/3 in C99.
    Thank you, it is good to see this formally confirmed.
    So this isn't like the latin alphabet characters, which can
    be non-contiguous in non-ASCII encodings, e.g. EBDIC.


    Kind regards,
    Ivan
    --
    http://ivan.vecerina.com
     
    Ivan Vecerina, Sep 30, 2003
    #14
  15. "Ivan Vecerina" <ivecATmyrealboxDOTcom> wrote:

    >
    > "Richard Heathfield" <> wrote in message
    > news:bla0q3$1sk$...
    >>
    >> "In both the source and execution basic character sets, the value of each
    >> character after 0 in the above list of decimal digits shall be one
    >> greater than the value of the previous."

    > 5.2.1/3 in C99.
    > Thank you, it is good to see this formally confirmed.
    > So this isn't like the latin alphabet characters, which can
    > be non-contiguous in non-ASCII encodings, e.g. EBDIC.


    Correct. The alphabet is a horse of a different kettle (or possibly a fish
    of a different colour), and you need to go the extra mile if you need
    portability. But you're fine with digits.

    --
    Richard Heathfield :
    "Usenet is a strange place." - Dennis M Ritchie, 29 July 1999.
    C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
    K&R answers, C books, etc: http://users.powernet.co.uk/eton
     
    Richard Heathfield, Sep 30, 2003
    #15
  16. Matt

    Morris Dovey Guest

    Matt wrote:

    > Given only putchar (no sprintf, itoa, etc.) write a routine putlong
    > that prints out an unsigned long in decimal. No array allowed.
    >
    > I have no idea if we can't use array to solve the problem.


    Matt...

    You might try something like:

    #include <stdio.h>

    void putlong(unsigned long x)
    { if (x > 10) putlong(x / 10);
    putchar(x % 10 + '0');
    }

    HTH
    --
    Morris Dovey
    West Des Moines, Iowa USA
    C links at http://www.iedu.com/c
     
    Morris Dovey, Sep 30, 2003
    #16
  17. Matt

    BruceS Guest

    "Dan Pop" <> wrote in message
    news:bl9g53$368$...
    > In <bl8hst$6rv$> Richard Heathfield

    <> writes:
    >
    > >"Ivan Vecerina" <ivecATmyrealboxDOTcom> wrote:
    > >
    > >>
    > >> "Richard Heathfield" <> wrote in message
    > >> news:bl7m4k$6i9$...
    > >>> "Ivan Vecerina" <ivecATmyrealboxDOTcom> wrote:
    > >>>
    > >>> > "Matt" <> wrote in message
    > >>> > news:...
    > >>> >> Given only putchar (no sprintf, itoa, etc.) write a routine putlong
    > >>> >> that prints out an unsigned long in decimal. No array allowed.
    > >>> >>
    > >>> >> I have no idea if we can't use array to solve the problem.
    > >>> >
    > >>> > One idea is to go with something like:
    > >>> > unsigned long exp = 10;
    > >>> > while(exp<val) exp*=10;
    > >>> > while( exp/=10 ) putchar( '0'+(val/exp)%10 );
    > >>> >
    > >>> > Bug left in on purpose, and optimizations are possible.
    > >>>
    > >>> Which bug? I count at least two.
    > >>
    > >> shush! ;) Is a portability problem included in your count?

    > >
    > >Well, the first is that it basically gives the wrong answer sometimes.

    The
    > >second is a namespace issue.

    >
    > No namespace issue, as long as exp has block scope.


    Thanks Dan, Richard, and Ivan. I learned something today.
     
    BruceS, Oct 2, 2003
    #17
  18. (Dan Pop) wrote in message news:<bl9g53$368$>...
    > In <bl8hst$6rv$> Richard Heathfield <> writes:
    >
    > >"Ivan Vecerina" <ivecATmyrealboxDOTcom> wrote:
    > >
    > >>
    > >> "Richard Heathfield" <> wrote in message
    > >> news:bl7m4k$6i9$...
    > >>> "Ivan Vecerina" <ivecATmyrealboxDOTcom> wrote:
    > >>>
    > >>> > "Matt" <> wrote in message
    > >>> > news:...
    > >>> >> Given only putchar (no sprintf, itoa, etc.) write a routine putlong
    > >>> >> that prints out an unsigned long in decimal. No array allowed.
    > >>> >>
    > >>> >> I have no idea if we can't use array to solve the problem.
    > >>> >
    > >>> > One idea is to go with something like:
    > >>> > unsigned long exp = 10;
    > >>> > while(exp<val) exp*=10;
    > >>> > while( exp/=10 ) putchar( '0'+(val/exp)%10 );
    > >>> >
    > >>> > Bug left in on purpose, and optimizations are possible.
    > >>>
    > >>> Which bug? I count at least two.
    > >>
    > >> shush! ;) Is a portability problem included in your count?

    > >
    > >Well, the first is that it basically gives the wrong answer sometimes. The
    > >second is a namespace issue.

    >
    > No namespace issue, as long as exp has block scope.


    But there is a conflict if <math.h> is included...

    7.1.3p5:
    ... If the program declares or defines an identifier in a context in
    which it is reserved (other than as allowed by 7.1.4), or defines a
    reserved identifier as a macro name, the behavior is undefined.

    --
    Peter
     
    Peter Nilsson, Oct 2, 2003
    #18
  19. Matt

    Dan Pop Guest

    In <> (Peter Nilsson) writes:

    > (Dan Pop) wrote in message news:<bl9g53$368$>...
    >> In <bl8hst$6rv$> Richard Heathfield <> writes:
    >>
    >> >"Ivan Vecerina" <ivecATmyrealboxDOTcom> wrote:
    >> >
    >> >>
    >> >> "Richard Heathfield" <> wrote in message
    >> >> news:bl7m4k$6i9$...
    >> >>> "Ivan Vecerina" <ivecATmyrealboxDOTcom> wrote:
    >> >>>
    >> >>> > "Matt" <> wrote in message
    >> >>> > news:...
    >> >>> >> Given only putchar (no sprintf, itoa, etc.) write a routine putlong
    >> >>> >> that prints out an unsigned long in decimal. No array allowed.
    >> >>> >>
    >> >>> >> I have no idea if we can't use array to solve the problem.
    >> >>> >
    >> >>> > One idea is to go with something like:
    >> >>> > unsigned long exp = 10;
    >> >>> > while(exp<val) exp*=10;
    >> >>> > while( exp/=10 ) putchar( '0'+(val/exp)%10 );
    >> >>> >
    >> >>> > Bug left in on purpose, and optimizations are possible.
    >> >>>
    >> >>> Which bug? I count at least two.
    >> >>
    >> >> shush! ;) Is a portability problem included in your count?
    >> >
    >> >Well, the first is that it basically gives the wrong answer sometimes. The
    >> >second is a namespace issue.

    >>
    >> No namespace issue, as long as exp has block scope.

    >
    >But there is a conflict if <math.h> is included...
    >
    > 7.1.3p5:
    > ... If the program declares or defines an identifier in a context in
    > which it is reserved (other than as allowed by 7.1.4), or defines a
    > reserved identifier as a macro name, the behavior is undefined.


    Could you, please, point out where the conflict is? After including
    <math.h>, exp is NOT a reserved identifier if defined with block scope.

    And if <math.h> defines an exp macro, it has to be a function-like macro,
    therefore there is still no conflict with

    unsigned long exp = 10;

    Dan
    --
    Dan Pop
    DESY Zeuthen, RZ group
    Email:
     
    Dan Pop, Oct 6, 2003
    #19
    1. Advertisements

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Edward Arthur

    Printing unsigned long long int's

    Edward Arthur, Nov 15, 2003, in forum: C++
    Replies:
    1
    Views:
    5,407
    Ivan Vecerina
    Nov 15, 2003
  2. shaun roe
    Replies:
    2
    Views:
    616
    Andrew Koenig
    Nov 6, 2004
  3. George Marsaglia

    Assigning unsigned long to unsigned long long

    George Marsaglia, Jul 8, 2003, in forum: C Programming
    Replies:
    1
    Views:
    970
    Eric Sosman
    Jul 8, 2003
  4. Replies:
    1
    Views:
    620
    Diez B. Roggisch
    Jun 1, 2005
  5. sridhar

    comparing unsigned long and unsigned int

    sridhar, Nov 1, 2004, in forum: C Programming
    Replies:
    6
    Views:
    704
    J. J. Farrell
    Nov 3, 2004
  6. Daniel Rudy

    unsigned long long int to long double

    Daniel Rudy, Sep 19, 2005, in forum: C Programming
    Replies:
    5
    Views:
    1,576
    Peter Shaggy Haywood
    Sep 20, 2005
  7. CFAN
    Replies:
    6
    Views:
    1,129
    Tor Rustad
    Apr 4, 2007
  8. pozz
    Replies:
    12
    Views:
    1,064
    Tim Rentsch
    Mar 20, 2011
Loading...