Solved

simple printf question

Posted on 1998-10-05
17
335 Views
Last Modified: 2010-04-15
float i = 3.33;
printf("%d",i)

From the program, the output is "0" Why? Can anyone explain to me what is the process  internally why the output is 0?  C language don't convert the type automatically? I heard about type cast where I can do something like (int) i to force it to interger, can I use this in the above program?
0
Comment
Question by:anik
  • 4
  • 3
  • 3
  • +5
17 Comments
 
LVL 86

Expert Comment

by:jkr
ID: 1253365
'%d' is the format token for an integer. To display floats, use

printf( "%f", i);

0
 
LVL 86

Expert Comment

by:jkr
ID: 1253366
Additionally, if you used a typecast (e.g. printf( "%d", (int) i); ), the output would have been '3'.
%f formats floats the 'normal' floating point representation, whilst %e would result in '3.33e+1'

0
 
LVL 51

Expert Comment

by:ahoffmann
ID: 1253367
I think the answer for "why results %d  in 0" is:

  if you (your program) interprets the bits stored in variable i
  as integer instead of float, the result is correctly 0.

Try it with  i=33.33; instead  ;-)

BTW, somoe people use:  printf("%g", i);

0
 

Author Comment

by:anik
ID: 1253368
Thank you Jkr but I already know that I should use %f but I just wonder why it show 0 when I use %d.

ahoffmann, you raise me another question. How floating point are stored in the variable? Since the computer can only store 0 and 1. And as you mentioned that if  I interpreted 3.33 in the variable i as integer it will be 0..Why?
0
 

Author Comment

by:anik
ID: 1253369
Adjusted points to 10
0
 
LVL 10

Expert Comment

by:rbr
ID: 1253370
You do something which is not correctly defined so the output could be anything. It depends on your hardware, your Os, your compiler. You have to check how ints and floats are stored and what assembler output your compiler produce if you want to know why 0 comes out.
0
 
LVL 5

Expert Comment

by:scrapdog
ID: 1253371
A floating point variable is stored with zeroes and ones.

In a float:

The first bit is for the sign, (1=negative, 0=positive)
The next 8 bits are for the exponent
And the remaining 23 bits are for the mantissa.

3.33 is represented by

33 x 10^1

(The sign is positive, the mantissa is .33, and the exponent is 1)
0
 
LVL 84

Expert Comment

by:ozo
ID: 1253372
That may be one way of representing them.
There are others.  We haven't been told what kind of machine anik is using here.
0
How to improve team productivity

Quip adds documents, spreadsheets, and tasklists to your Slack experience
- Elevate ideas to Quip docs
- Share Quip docs in Slack
- Get notified of changes to your docs
- Available on iOS/Android/Desktop/Web
- Online/Offline

 
LVL 51

Expert Comment

by:ahoffmann
ID: 1253373
the question was answered, see my and  scrapdog's comment.
If you want to know how programs, compileres, operating systems
etc. interprete the 0s and 1s, you should by a good book about computer fundamentals. It's a really long story ;-)
0
 
LVL 4

Expert Comment

by:NicoLaan
ID: 1253374
Try the following for learning purposes:

#include <stdio.h>

void main(void)
{
 char *ch;
 float f;
 int i;

 ch = &f;
 f = 2;

 printf("\n");
 for (i=0; i<sizeof(float); i++)
  printf(" %0X", ch[i]);
}

Perhaps write some function to print ch[i] as a binairy value.
0
 

Expert Comment

by:JHandby
ID: 1253375
Anik,


The reason that the compiler can't convert the float to an int automatically is to do with the fact that printf is declared to take a variable number of arguments. If you look in stdio.h, you'll probably see printf declared something like this:

int printf(const char *, ...);

The first argument, of type const char *, is the printf format string. This means that the compiler will be able to check the type of the first argument at compile time. The "..." indicates to the compiler that there will be zero or more arguments supplied, but that the compiler cannot make any assumptions about how many there will be, or what type they will be. This makes sense, if you think about how printf gets used:

printf("Just a string");
printf("%d green bottles", num_bottles);
printf("%d / %d = %lf", num, denom, (double)num / denom);

These are all valid printf calls (at least I hope they are :-) ), with different numbers and types of arguments. There's no way that could be type-checked or automatically converted at compile-time.

Because the compiler doesn't know how many arguments there'll be, the printf function itself is responsible for getting hold of the arguments passed to it at runtime (which is basically done internally by getting a pointer to the first argument, and moving it through memory to point to each extra argument in turn). The only information available to printf to tell it what type the arguments are and how many there should be is what you supply in your format string. So, if you tell printf to expect an int (by using "%d" in your format string), then it will try to get hold of the next argument and pull it out as an int. If you've actually passed in a float, there'll be trouble...

It's possible to create all sorts of fantastic bugs by using printf wrong :-)

For more information on variable-argument functions, look at  stdarg.h or varargs.h, depending on what flavour of compiler you're using.



Hope this helps



Jason

0
 

Author Comment

by:anik
ID: 1253376
Thank you very much for all of your help.
0
 
LVL 10

Expert Comment

by:rbr
ID: 1253377
And to whom will you give the points?
0
 

Author Comment

by:anik
ID: 1253378
Please get the point ahoffman and Jhandby.
0
 
LVL 51

Accepted Solution

by:
ahoffmann earned 10 total points
ID: 1253379
Answer again.

I think the answer for "why results %d  in 0" is:

        if you (your program) interprets the bits stored in variable i
        as integer instead of float, the result is correctly 0.

Try it with  i=33.33; instead  ;-)

BTW, somoe people use:  printf("%g", i);
0
 

Expert Comment

by:JHandby
ID: 1253380
Guess I missed that one. Ah well :-)


Jason

0
 

Expert Comment

by:JHandby
ID: 1253381
Sorry, I'm dumb. I've just seen your duplicate question...
0

Featured Post

Enabling OSINT in Activity Based Intelligence

Activity based intelligence (ABI) requires access to all available sources of data. Recorded Future allows analysts to observe structured data on the open, deep, and dark web.

Join & Write a Comment

Suggested Solutions

Title # Comments Views Activity
posix semaphore deadlock 13 108
mixing C++ and C code elegantly 10 150
Finding a good hash function 4 116
C language IDE – Compilers installation 14 58
An Outlet in Cocoa is a persistent reference to a GUI control; it connects a property (a variable) to a control.  For example, it is common to create an Outlet for the text field GUI control and change the text that appears in this field via that Ou…
Windows programmers of the C/C++ variety, how many of you realise that since Window 9x Microsoft has been lying to you about what constitutes Unicode (http://en.wikipedia.org/wiki/Unicode)? They will have you believe that Unicode requires you to use…
The goal of this video is to provide viewers with basic examples to understand and use pointers in the C programming language.
Video by: Grant
The goal of this video is to provide viewers with basic examples to understand and use nested-loops in the C programming language.

707 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

15 Experts available now in Live!

Get 1:1 Help Now