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. Advertising

  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. Advertising

  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. Advertising

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. George Marsaglia

    Assigning unsigned long to unsigned long long

    George Marsaglia, Jul 8, 2003, in forum: C Programming
    Replies:
    1
    Views:
    671
    Eric Sosman
    Jul 8, 2003
  2. Replies:
    1
    Views:
    450
    Diez B. Roggisch
    Jun 1, 2005
  3. sridhar

    comparing unsigned long and unsigned int

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

    unsigned long long int to long double

    Daniel Rudy, Sep 19, 2005, in forum: C Programming
    Replies:
    5
    Views:
    1,184
    Peter Shaggy Haywood
    Sep 20, 2005
  5. pozz
    Replies:
    12
    Views:
    731
    Tim Rentsch
    Mar 20, 2011
Loading...

Share This Page