printf headache

J

Joe Smith

#include <stdio.h>

int main(void)
{
unsigned long gcd(unsigned long m, unsigned long n);
unsigned long m;
unsigned long n;
unsigned long t;
m = 2520;
n = 154;
t = gcd(m, n);
printf("%f is gcd\n", t);
return 0;
}



unsigned long gcd(unsigned long m, unsigned long n)
{
if(m < n)
{
unsigned long temp = m;
m = n;
n = temp;
}
if(n > 0)
{
unsigned long r;
do
{
r = m % n;
m = n;
n = r ? r : n;
} while(r > 0);
}

return n;
}
/* end code */
This compiles and behaves with the exception of the printf. I've scoured
K&R print flags to %% and am out of guesses. Joe
 
I

Ian Collins

Joe said:
#include <stdio.h>

int main(void)
{
unsigned long gcd(unsigned long m, unsigned long n);
unsigned long m;
unsigned long n;
unsigned long t;
m = 2520;
n = 154;
t = gcd(m, n);
printf("%f is gcd\n", t);

You are using %f (float) to print an unsigned long. Try %d.
 
J

Joe Smith

"Ian Collins"
Joe Smith wrote: snip

You are using %f (float) to print an unsigned long. Try %d.
Yeah, that'll do it. In the development by Gallian he writes out the eqns
for what happens for this division algorithm with 2520 and 154 as input:
2520 = 154*16 +56
154=56*2+42
56=42*1+14
42=14*3+0
It is unclear to me whether this is where prop 2 book 7 Euclid finishes.
Mr. Heathfield, who kindly provided this code from Knuth, and I have been
talking past each other elsewhere as I was under the impression that the
Euclidean algorithm would ultimately express two numbers as a linear
combination. To do this, Gallian rewrites the eq's and substitutes:
56 = 2520+154(-16)
42=154+56(-2)
14=56+42(-1)
=56+[154+56(-2)](-1)
=56*3+154(-1)
=[2520 +154(-16)]3+154(-1)
14=2520*3 + 154(-49)

I think I need a memory technique to do what Professor Gallian does above.
Furthermore, one does not know a priori how many steps the division
algorithm requires. It would seem to me that I would have to run the
division algorithm and remember something each time. (Finally a question)
Given the truth of the previous sentence, what is the stingiest way to do it
in C? Joe
 
O

Old Wolf

Robert said:
Or %lu if you want to print an unsigned long as opposed to an
unsigned int followed by the letter l :)

I actually did that one time. And the printer was using a font in
which the number 1 is indistinguishable from the letter l. I spent
some time tearing my hair out as to why my values which
should have been 4 and 6 were printing out as 41 and 61 :)
 
R

Robert Gamble

Old said:
I actually did that one time. And the printer was using a font in
which the number 1 is indistinguishable from the letter l. I spent
some time tearing my hair out as to why my values which
should have been 4 and 6 were printing out as 41 and 61 :)

I don't always remember which way it goes either and %ul is somewhat
more intuitive (for Unsigned Long); luckily both my editor and compiler
know which it is ;)

Robert Gamble
 
I

Ian Collins

Robert said:
All conforming ones do, what does yours do?

Robert Gamble
#include <stdio.h>

int
main(void)
{
unsigned long l = (unsigned long)-1;

printf( "%d %ul %ld %lu\n", l, l, l, l );
}

-1 4294967295l -1 4294967295

With both Sun cc and gcc.
 
I

Ian Collins

Ian said:
#include <stdio.h>

int
main(void)
{
unsigned long l = (unsigned long)-1;

printf( "%d %ul %ld %lu\n", l, l, l, l );
}

-1 4294967295l -1 4294967295
^
Bugger, I fell into the 1 != l trap...
 
R

Robert Gamble

Ian said:
#include <stdio.h>

int
main(void)
{
unsigned long l = (unsigned long)-1;

printf( "%d %ul %ld %lu\n", l, l, l, l );
}

-1 4294967295l -1 4294967295

With both Sun cc and gcc.

I am not sure what you are trying to demonstrate here and your example
contains more than one instance of undefined behavior which gcc points
out when executed with the appropriate options:

warning: format '%d' expects type 'int', but argument 2 has
type 'long unsigned int'
warning: format '%u' expects type 'unsigned int', but argument
3 has type 'long unsigned int'

Notice that the letter l was printed after the value corresponding to
the %ul conversion specifier in your example which, aside from the
above-mentioned UB, is in line with my assertion.

Here is a more appropriate example:

#include <stdio.h>

int
main(void)
{
unsigned long l = 42;
printf( "%ul %lu\n", (unsigned)l, l );
return 0;
}

The cast is required to prevent undefined behavior and the result
should be:
42l 42

Robert Gamble
 
C

CBFalconer

Joe said:
#include <stdio.h>

int main(void)
{
unsigned long gcd(unsigned long m, unsigned long n);
unsigned long m;
unsigned long n;
unsigned long t;
m = 2520;
n = 154;
t = gcd(m, n);
printf("%f is gcd\n", t);
return 0;
}

unsigned long gcd(unsigned long m, unsigned long n)
{
if(m < n)
{
unsigned long temp = m;
m = n;
n = temp;
}
if(n > 0)
{
unsigned long r;
do
{
r = m % n;
m = n;
n = r ? r : n;
} while(r > 0);
}

return n;
}
/* end code */
This compiles and behaves with the exception of the printf. I've scoured
K&R print flags to %% and am out of guesses. Joe

Apparently noone has bothered to notice that you are calling gcd
before declaring it, and that the system thus assumes gcd to return
an int.

The simple practice of writing subroutines ahead of routines that
call them will avoid this sort of silly error. With proper flags
the better compilers would have also complained.

--
"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson
More details at: <http://cfaj.freeshell.org/google/>
Also see <http://www.safalra.com/special/googlegroupsreply/>
 
I

Ian Collins

Apparently noone has bothered to notice that you are calling gcd
before declaring it, and that the system thus assumes gcd to return
an int.
Note the first line of main.
The simple practice of writing subroutines ahead of routines that
call them will avoid this sort of silly error. With proper flags
the better compilers would have also complained.
Not in this case, but I agree with writing subroutines before they are used.
 
J

Joe Smith

CBFalconer said:
Apparently noone has bothered to notice that you are calling gcd
before declaring it, and that the system thus assumes gcd to return
an int.
I believe that this is what forked me.
The simple practice of writing subroutines ahead of routines that
call them will avoid this sort of silly error. With proper flags
the better compilers would have also complained.
I struggle with flags in the contemporary programming environment. As to the
former contention, Mr. Knuth wrote the subroutine while I was watching Tom &
Jerry. I would like to characterize the improper call as part of the rust
I'm trying to shed. Joe
 
P

pete

Robert said:
That's wrong as well, it should be %lu.

I usually write "long unsigned" instead of "unsigned long",
to remind me not to make a mistake like that, again.
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,183
Messages
2,570,968
Members
47,517
Latest member
TashaLzw39

Latest Threads

Top