Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > prints out an unsigned long in decimal

Reply
Thread Tools

prints out an unsigned long in decimal

 
 
CBFalconer
Guest
Posts: n/a
 
      09-29-2003
Richard Heathfield wrote:
> "Ivan Vecerina" <ivecATmyrealboxDOTcom> wrote:
> > "Richard Heathfield" wrote in message
> >> "Ivan Vecerina" <ivecATmyrealboxDOTcom> wrote:
> >> > "Matt" <(E-Mail Removed)> 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 ((E-Mail Removed)) ((E-Mail Removed))
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net> USE worldnet address!


 
Reply With Quote
 
 
 
 
Dan Pop
Guest
Posts: n/a
 
      09-29-2003
In <bl8hst$6rv$(E-Mail Removed)> Richard Heathfield <(E-Mail Removed)> writes:

>"Ivan Vecerina" <ivecATmyrealboxDOTcom> wrote:
>
>>
>> "Richard Heathfield" <(E-Mail Removed)> wrote in message
>> news:bl7m4k$6i9$(E-Mail Removed)...
>>> "Ivan Vecerina" <ivecATmyrealboxDOTcom> wrote:
>>>
>>> > "Matt" <(E-Mail Removed)> wrote in message
>>> > news:(E-Mail Removed) 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: http://www.velocityreviews.com/forums/(E-Mail Removed)
 
Reply With Quote
 
 
 
 
Richard Heathfield
Guest
Posts: n/a
 
      09-29-2003
Ivan Vecerina wrote:

> "Richard Heathfield" <(E-Mail Removed)> wrote in message
> news:bl8hst$6rv$(E-Mail Removed)...
> | "Ivan Vecerina" <ivecATmyrealboxDOTcom> wrote:
> | > "Richard Heathfield" <(E-Mail Removed)> wrote in message
> | > news:bl7m4k$6i9$(E-Mail Removed)...
> | >> "Ivan Vecerina" <ivecATmyrealboxDOTcom> wrote:
> | >> > "Matt" <(E-Mail Removed)> wrote in message
> | >> > news:(E-Mail Removed) 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 : (E-Mail Removed)
"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
 
Reply With Quote
 
Ivan Vecerina
Guest
Posts: n/a
 
      09-29-2003

"Richard Heathfield" <(E-Mail Removed)> wrote in message
news:bla0q3$1sk$(E-Mail Removed)...
> Ivan Vecerina wrote:
> > "Richard Heathfield" <(E-Mail Removed)> wrote in message
> > news:bl8hst$6rv$(E-Mail Removed)...
> > | 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


 
Reply With Quote
 
Richard Heathfield
Guest
Posts: n/a
 
      09-30-2003
"Ivan Vecerina" <ivecATmyrealboxDOTcom> wrote:

>
> "Richard Heathfield" <(E-Mail Removed)> wrote in message
> news:bla0q3$1sk$(E-Mail Removed)...
>>
>> "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 : (E-Mail Removed)
"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
 
Reply With Quote
 
Morris Dovey
Guest
Posts: n/a
 
      09-30-2003
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

 
Reply With Quote
 
BruceS
Guest
Posts: n/a
 
      10-02-2003

"Dan Pop" <(E-Mail Removed)> wrote in message
news:bl9g53$368$(E-Mail Removed)...
> In <bl8hst$6rv$(E-Mail Removed)> Richard Heathfield

<(E-Mail Removed)> writes:
>
> >"Ivan Vecerina" <ivecATmyrealboxDOTcom> wrote:
> >
> >>
> >> "Richard Heathfield" <(E-Mail Removed)> wrote in message
> >> news:bl7m4k$6i9$(E-Mail Removed)...
> >>> "Ivan Vecerina" <ivecATmyrealboxDOTcom> wrote:
> >>>
> >>> > "Matt" <(E-Mail Removed)> wrote in message
> >>> > news:(E-Mail Removed) 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.


Thanks Dan, Richard, and Ivan. I learned something today.


 
Reply With Quote
 
Peter Nilsson
Guest
Posts: n/a
 
      10-02-2003
(E-Mail Removed) (Dan Pop) wrote in message news:<bl9g53$368$(E-Mail Removed)>...
> In <bl8hst$6rv$(E-Mail Removed)> Richard Heathfield <(E-Mail Removed)> writes:
>
> >"Ivan Vecerina" <ivecATmyrealboxDOTcom> wrote:
> >
> >>
> >> "Richard Heathfield" <(E-Mail Removed)> wrote in message
> >> news:bl7m4k$6i9$(E-Mail Removed)...
> >>> "Ivan Vecerina" <ivecATmyrealboxDOTcom> wrote:
> >>>
> >>> > "Matt" <(E-Mail Removed)> wrote in message
> >>> > news:(E-Mail Removed) 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
 
Reply With Quote
 
Dan Pop
Guest
Posts: n/a
 
      10-06-2003
In <(E-Mail Removed) > (E-Mail Removed) (Peter Nilsson) writes:

>(E-Mail Removed) (Dan Pop) wrote in message news:<bl9g53$368$(E-Mail Removed)>...
>> In <bl8hst$6rv$(E-Mail Removed)> Richard Heathfield <(E-Mail Removed)> writes:
>>
>> >"Ivan Vecerina" <ivecATmyrealboxDOTcom> wrote:
>> >
>> >>
>> >> "Richard Heathfield" <(E-Mail Removed)> wrote in message
>> >> news:bl7m4k$6i9$(E-Mail Removed)...
>> >>> "Ivan Vecerina" <ivecATmyrealboxDOTcom> wrote:
>> >>>
>> >>> > "Matt" <(E-Mail Removed)> wrote in message
>> >>> > news:(E-Mail Removed) 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: (E-Mail Removed)
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
(int) -> (unsigned) -> (int) or (unsigned) -> (int) -> (unsigned):I'll loose something? pozz C Programming 12 03-20-2011 11:32 PM
Having compilation error: no match for call to (const __gnu_cxx::hash<long long int>) (const long long int&) veryhotsausage C++ 1 07-04-2008 05:41 PM
unsigned long long int to long double Daniel Rudy C Programming 5 09-20-2005 02:37 AM
unsigned long to unsigned char ashtonn@gmail.com Python 1 06-01-2005 07:00 PM
Assigning unsigned long to unsigned long long George Marsaglia C Programming 1 07-08-2003 05:16 PM



Advertisments