printf("%f") question

I

Ioannis Vranos

If we want to print a float with printf, a printf("%f", x); is
sufficient, or a cast is needed like in printf("%f", (double)x); ?
 
H

Harald van Dijk

If we want to print a float with printf, a printf("%f", x); is
sufficient, or a cast is needed like in printf("%f", (double)x); ?

Any float argument to the variable arguments of a function will be
promoted to double. Both are fine.
 
I

Ioannis Vranos

Harald said:
Any float argument to the variable arguments of a function will be
promoted to double. Both are fine.


I suppose the following are also correct:

signed char sc= 15;
unsigned char uc= 130;

printf("%d\t%hu\t%u", sc, uc, uc);
 
H

Harald van Dijk

I suppose the following are also correct:

signed char sc= 15;
unsigned char uc= 130;

printf("%d\t%hu\t%u", sc, uc, uc);

On most systems, unsigned char will be promoted to signed int, which
should be printed using %d. You can usually -- probably on all existing
implementations -- get away with printing a signed int using %u, or an
unsigned int using %d, so long as the value is within the common range,
but it's not correct.
 
M

Martin Ambuhl

Ioannis said:
If we want to print a float with printf, a printf("%f", x); is
sufficient, or a cast is needed like in printf("%f", (double)x); ?

x will be promoted to a double, following the normal promotion rules for
arguments. The cast is unnecessary.
 
K

Keith Thompson

Harald van Dijk said:
On most systems, unsigned char will be promoted to signed int, which
should be printed using %d. You can usually -- probably on all existing
implementations -- get away with printing a signed int using %u, or an
unsigned int using %d, so long as the value is within the common range,
but it's not correct.

signed char definitely promotes to (signed) int, so the "%d" is ok.

The "%hu" should be "%hhu" ("%hu" is for unsigned short). The "%hhu"
format prints a value of type unsigned char; "the argument will have
been promoted according to the integer promotions, but its value shall
be converted to signed char or unsigned char before printing" (C99
7.19.6.1p7). That's exactly what "%hhu" is for.

Harald is correct about the "%u" format; "%hhu" is better than "%u",
even though "%u" is very likely to work as expected.
 
I

Ioannis Vranos

Keith said:
signed char definitely promotes to (signed) int, so the "%d" is ok.

The "%hu" should be "%hhu" ("%hu" is for unsigned short). The "%hhu"
format prints a value of type unsigned char; "the argument will have
been promoted according to the integer promotions, but its value shall
be converted to signed char or unsigned char before printing" (C99
7.19.6.1p7). That's exactly what "%hhu" is for.

Harald is correct about the "%u" format; "%hhu" is better than "%u",
even though "%u" is very likely to work as expected.


Thanks for the answer, I forgot to mention that I am talking about
C90/C95 here.
 
I

Ioannis Vranos

santosh said:
In which case you'll have to use %u.


Thanks for the answer. So, if I want to print the numeric value of an
unsigned char , can I use printf("%u") without a cast?
 
Y

ymuntyan

Thanks for the answer. So, if I want to print the numeric value of an
unsigned char , can I use printf("%u") without a cast?

See http://groups.google.com/group/comp.std.c/browse_thread/thread/7af31515d3ae7f2b/f1cc2a95425424f0
It's about a little different thing, passing int as a char, but
I don't think it makes much difference here, because there is no
definitive answer anyway. You can google more, there were much
bigger threads about this stuff (including passing char instead
of int, IIRC).

Yevgen
 
Y

ymuntyan

Does any of these threads reach a conclusion? :)

Are you kidding? A resolved DR would be a conclusion, otherwise
you read what people say and either agree or disagree. I personally
stick to the following: it's UB, but works fine here (where "here"
is "everywhere").

Yevgen
 
I

Ioannis Vranos

Are you kidding? A resolved DR would be a conclusion, otherwise
you read what people say and either agree or disagree. I personally
stick to the following: it's UB, but works fine here (where "here"
is "everywhere").


Well, I think casting the value to the expected type by the printf(), is
the safest solution.
 
P

Peter Nilsson

... So, if I want to print the numeric value of an
unsigned char , can I use printf("%u") without a
cast?

Certainly...

unsigned char uc;
printf("%u", 0u + uc);
 
I

Ioannis Vranos

Peter said:
Certainly...

unsigned char uc;
printf("%u", 0u + uc);


I mean with the unsigned char variable alone, not with an interaction
with an unsigned int constant or variable.
 
P

Peter Nilsson

Ioannis Vranos said:
I mean with the unsigned char variable alone,

It's my opinion that the literal wording of the standard
differs from the stated intent for both C90/95 and C99.
The intent is that a common value to both should work as
an argument to either signed/unsigned version of an
integer rank.

However, the standard clearly ambiguates this, if not
actually precludes it, in many places. For instance,
va_arg() is required to work this way, but fprintf isn't
required to use va_arg().

The point is, if you want to be pedantic, then play it
safe.
not with an interaction with an unsigned int constant
or variable.

The reason I throw in a 0u is precisely to avoid
ambiguities around the promotion of unsigned char.
A cast would be sufficient, and more idiomatic, but
it's ugly IMHO.
 

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
473,776
Messages
2,569,603
Members
45,189
Latest member
CryptoTaxSoftware

Latest Threads

Top