440,213 Members | 2,108 Online
Need help? Post your question and get tips & solutions from a community of 440,213 IT Pros & Developers. It's quick & easy.

# prints out an unsigned long in decimal

 P: n/a 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. Nov 13 '05 #1
18 Replies

 P: n/a 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 (pa*****@cc.helsinki.fi) ---------------------------\ | 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 Nov 13 '05 #2

 P: n/a "Matt" wrote in message news:ba**************************@posting.google.c om... 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

 P: n/a "Ivan Vecerina" wrote: "Matt" wrote in message news:ba**************************@posting.google.c om... 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

 P: n/a 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:jo********@earthlink.net "Everything should be made as simple as possible, but not simpler." --- Albert Einstein --- Nov 13 '05 #5

 P: n/a "Richard Heathfield" wrote in message news:bl**********@hercules.btinternet.com... "Ivan Vecerina" wrote: "Matt" wrote in message news:ba**************************@posting.google.c om... 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

 P: n/a "Ivan Vecerina" wrote: "Richard Heathfield" wrote in message news:bl**********@hercules.btinternet.com... "Ivan Vecerina" wrote: > "Matt" wrote in message > news:ba**************************@posting.google.c om... >> 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 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 : bi****@eton.powernet.co.uk "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 Nov 13 '05 #7

 P: n/a "Richard Heathfield" wrote in message news:bl**********@sparta.btinternet.com... | "Ivan Vecerina" wrote: | > "Richard Heathfield" wrote in message | > news:bl**********@hercules.btinternet.com... | >> "Ivan Vecerina" wrote: | >> > "Matt" wrote in message | >> > news:ba**************************@posting.google.c om... | >> >> 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> > 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 ? 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 Nov 13 '05 #8

 P: n/a 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 ? That, plus val not being declared... :) -- Martijn http://www.sereneconcepts.nl Nov 13 '05 #9

 P: n/a Ivan Vecerina wrote: A conflict with the exp() function if using ? How about regardless of whether or not using ? -- pete Nov 13 '05 #10

 P: n/a Richard Heathfield wrote: "Ivan Vecerina" wrote: "Richard Heathfield" wrote in message "Ivan Vecerina" 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 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 (cb********@yahoo.com) (cb********@worldnet.att.net) Available for consulting/temporary embedded and systems. USE worldnet address! Nov 13 '05 #11

 P: n/a In Richard Heathfield writes: "Ivan Vecerina" wrote: "Richard Heathfield" wrote in message news:bl**********@hercules.btinternet.com... "Ivan Vecerina" wrote: > "Matt" wrote in message > news:ba**************************@posting.google.c om... >> 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 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. Thesecond is a namespace issue. No namespace issue, as long as exp has block scope. Dan -- Dan Pop DESY Zeuthen, RZ group Email: Da*****@ifh.de Nov 13 '05 #12

 P: n/a Ivan Vecerina wrote: "Richard Heathfield" wrote in message news:bl**********@sparta.btinternet.com... | "Ivan Vecerina" wrote: | > "Richard Heathfield" wrote in message | > news:bl**********@hercules.btinternet.com... | >> "Ivan Vecerina" wrote: | >> > "Matt" wrote in message | >> > news:ba**************************@posting.google.c om... | >> >> 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> > 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 ? 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 : bi****@eton.powernet.co.uk "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 Nov 13 '05 #13

 P: n/a "Richard Heathfield" wrote in message news:bl**********@sparta.btinternet.com... Ivan Vecerina wrote: "Richard Heathfield" wrote in message news:bl**********@sparta.btinternet.com... | 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 ? 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 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 : 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 Nov 13 '05 #14

 P: n/a "Ivan Vecerina" wrote: "Richard Heathfield" wrote in message news:bl**********@sparta.btinternet.com... "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 : bi****@eton.powernet.co.uk "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 Nov 13 '05 #15

 P: n/a 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 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 Nov 13 '05 #16

 P: n/a "Dan Pop" wrote in message news:bl**********@sunnews.cern.ch... In Richard Heathfield writes:"Ivan Vecerina" wrote: "Richard Heathfield" wrote in message news:bl**********@hercules.btinternet.com... "Ivan Vecerina" wrote: > "Matt" wrote in message > news:ba**************************@posting.google.c om... >> 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 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. Thesecond is a namespace issue. No namespace issue, as long as exp has block scope. Thanks Dan, Richard, and Ivan. I learned something today. Nov 13 '05 #17

 P: n/a Da*****@cern.ch (Dan Pop) wrote in message news:... In Richard Heathfield writes:"Ivan Vecerina" wrote: "Richard Heathfield" wrote in message news:bl**********@hercules.btinternet.com... "Ivan Vecerina" wrote: > "Matt" wrote in message > news:ba**************************@posting.google.c om... >> 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 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. Thesecond is a namespace issue. No namespace issue, as long as exp has block scope. But there is a conflict if 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 Nov 13 '05 #18

 P: n/a In <63**************************@posting.google.com > ai***@acay.com.au (Peter Nilsson) writes: Da*****@cern.ch (Dan Pop) wrote in message news:... In Richard Heathfield writes: >"Ivan Vecerina" wrote: > >> >> "Richard Heathfield" wrote in message >> news:bl**********@hercules.btinternet.com... >>> "Ivan Vecerina" wrote: >>> >>> > "Matt" wrote in message >>> > news:ba**************************@posting.google.c om... >>> >> 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>> > 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 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 , exp is NOT a reserved identifier if defined with block scope. And if 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: Da*****@ifh.de Nov 13 '05 #19

### This discussion thread is closed

Replies have been disabled for this discussion.