473,320 Members | 2,146 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,320 software developers and data experts.

prints out an unsigned long in decimal

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 6940
Matt <jr********@hotmail.com> 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
"Matt" <jr********@hotmail.com> 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<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
Nov 13 '05 #3
"Ivan Vecerina" <ivecATmyrealboxDOTcom> wrote:
"Matt" <jr********@hotmail.com> 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<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 : 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 #4
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

"Richard Heathfield" <do******@address.co.uk.invalid> wrote in message
news:bl**********@hercules.btinternet.com...
"Ivan Vecerina" <ivecATmyrealboxDOTcom> wrote:
"Matt" <jr********@hotmail.com> 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<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
Nov 13 '05 #6
"Ivan Vecerina" <ivecATmyrealboxDOTcom> wrote:

"Richard Heathfield" <do******@address.co.uk.invalid> wrote in message
news:bl**********@hercules.btinternet.com...
"Ivan Vecerina" <ivecATmyrealboxDOTcom> wrote:
> "Matt" <jr********@hotmail.com> 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<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 : 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
"Richard Heathfield" <do******@address.co.uk.invalid> wrote in message
news:bl**********@sparta.btinternet.com...
| "Ivan Vecerina" <ivecATmyrealboxDOTcom> wrote:
| > "Richard Heathfield" <do******@address.co.uk.invalid> wrote in message
| > news:bl**********@hercules.btinternet.com...
| >> "Ivan Vecerina" <ivecATmyrealboxDOTcom> wrote:
| >> > "Matt" <jr********@hotmail.com> 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<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
Nov 13 '05 #8
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
Nov 13 '05 #9
Ivan Vecerina wrote:
A conflict with the exp() function if using <math.h> ?


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

--
pete
Nov 13 '05 #10
Richard Heathfield wrote:
"Ivan Vecerina" <ivecATmyrealboxDOTcom> wrote:
"Richard Heathfield" wrote in message
"Ivan Vecerina" <ivecATmyrealboxDOTcom> wrote:
> "Matt" <jr********@hotmail.com> 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 (cb********@yahoo.com) (cb********@worldnet.att.net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net> USE worldnet address!
Nov 13 '05 #11
In <bl**********@sparta.btinternet.com> Richard Heathfield <do******@address.co.uk.invalid> writes:
"Ivan Vecerina" <ivecATmyrealboxDOTcom> wrote:

"Richard Heathfield" <do******@address.co.uk.invalid> wrote in message
news:bl**********@hercules.btinternet.com...
"Ivan Vecerina" <ivecATmyrealboxDOTcom> wrote:

> "Matt" <jr********@hotmail.com> 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<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: Da*****@ifh.de
Nov 13 '05 #12
Ivan Vecerina wrote:
"Richard Heathfield" <do******@address.co.uk.invalid> wrote in message
news:bl**********@sparta.btinternet.com...
| "Ivan Vecerina" <ivecATmyrealboxDOTcom> wrote:
| > "Richard Heathfield" <do******@address.co.uk.invalid> wrote in message
| > news:bl**********@hercules.btinternet.com...
| >> "Ivan Vecerina" <ivecATmyrealboxDOTcom> wrote:
| >> > "Matt" <jr********@hotmail.com> 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<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 : 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

"Richard Heathfield" <do******@address.co.uk.invalid> wrote in message
news:bl**********@sparta.btinternet.com...
Ivan Vecerina wrote:
"Richard Heathfield" <do******@address.co.uk.invalid> 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 <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
Nov 13 '05 #14
"Ivan Vecerina" <ivecATmyrealboxDOTcom> wrote:

"Richard Heathfield" <do******@address.co.uk.invalid> 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
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

Nov 13 '05 #16

"Dan Pop" <Da*****@cern.ch> wrote in message
news:bl**********@sunnews.cern.ch...
In <bl**********@sparta.btinternet.com> Richard Heathfield <do******@address.co.uk.invalid> writes:
"Ivan Vecerina" <ivecATmyrealboxDOTcom> wrote:

"Richard Heathfield" <do******@address.co.uk.invalid> wrote in message
news:bl**********@hercules.btinternet.com...
"Ivan Vecerina" <ivecATmyrealboxDOTcom> wrote:

> "Matt" <jr********@hotmail.com> 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<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. 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
Da*****@cern.ch (Dan Pop) wrote in message news:<bl**********@sunnews.cern.ch>...
In <bl**********@sparta.btinternet.com> Richard Heathfield <do******@address.co.uk.invalid> writes:
"Ivan Vecerina" <ivecATmyrealboxDOTcom> wrote:

"Richard Heathfield" <do******@address.co.uk.invalid> wrote in message
news:bl**********@hercules.btinternet.com...
"Ivan Vecerina" <ivecATmyrealboxDOTcom> wrote:

> "Matt" <jr********@hotmail.com> 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<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
Nov 13 '05 #18
In <63**************************@posting.google.com > ai***@acay.com.au (Peter Nilsson) writes:
Da*****@cern.ch (Dan Pop) wrote in message news:<bl**********@sunnews.cern.ch>...
In <bl**********@sparta.btinternet.com> Richard Heathfield <do******@address.co.uk.invalid> writes:
>"Ivan Vecerina" <ivecATmyrealboxDOTcom> wrote:
>
>>
>> "Richard Heathfield" <do******@address.co.uk.invalid> wrote in message
>> news:bl**********@hercules.btinternet.com...
>>> "Ivan Vecerina" <ivecATmyrealboxDOTcom> wrote:
>>>
>>> > "Matt" <jr********@hotmail.com> 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<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: Da*****@ifh.de
Nov 13 '05 #19

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
by: Edward Arthur | last post by:
Hi, I'm trying to convert a string to an unsigned long long int. % /tmp/long str 0x20000 base 16 decimal 131072 hex 20000 str 0x1abcd8765
7
by: William Payne | last post by:
Hello, I have a variable of type unsigned long. It has a number of bits set (with set I mean they equal one). I need to determine those bits and their position and create new numbers from them. For...
9
by: Protoman | last post by:
I'm trying to print a complex number and i get this as output: Phi: (1.618034,0.000000). What does it mean? How do I get it to print normally? Here's the code: ----------fib.hpp-------------...
10
by: Peter Piper | last post by:
A Quick question if someone could help, im sure this has been asked before, but googling is getting me now where slowly. Is it possible to get an unsigned 32 bit integer field in Access. Im...
7
by: Golan | last post by:
Hi, I need to convert a Binary value to Decimal. I've been told that the value is an unsigned one. How can I do this? I use memcpy into an unsigned char variable, but when I print the value I got...
9
by: Fred Ma | last post by:
Hello, I've been trying to clear up a confusion about integer promotions during expression evaluation. I've checked the C FAQ and C++ FAQ (they are different languages, but I was hoping one...
14
by: me2 | last post by:
I am writing a little base conversion utility called base.c. This is what base does. $ base -127 Signed decimal: -127 Unsigned decimal: 4294967169 Hexidecimal: ...
6
by: CFAN | last post by:
Here is a example of double-type-conversion char * __cdecl _itoa ( int val, char *buf, int radix ) { if (radix == 10 && val < 0) xtoa((unsigned long)val, buf, radix, 1); else
107
by: bmshivaraj | last post by:
Hi, Could any one tell me how to convert a unsigned long value into string (char *) ? In C++ there is a function _ultoa so wanted a similar one in C . Regards, Shivaraj
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
0
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
1
by: Shællîpôpï 09 | last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.