# New programmer missing somthing -- help!

This is a discussion on New programmer missing somthing -- help! within the C Programming forums, part of the General Programming Boards category; I am very new to programming (a whole week now!) and I picked up a copy of C primer plus ...

1. ## New programmer missing somthing -- help!

I am very new to programming (a whole week now!) and I picked up a copy of C primer plus 5ed. I have been doing pretty well so far considering I have nobody to ask for clarification. I am on an exercise that wants me to display age in seconds. Everything is working except the math. I think it is an issue with data types, but I have no idea. If anyone can point me in the right direction I would appreciate it.
On a side note, I got this book because it was recommended. Does anyone have any other recommendations for someone just learning programming?

Here is what I have so far. It is giving an answer that is way to high.
Code:
```// tells age in seconds

#include <stdio.h>

int main(void)

{

int age;

printf("how old are you?\n");

scanf("%d", &age);

printf("no, you are %d.\n", age * 3.156e7);

return 0;

}```
Oh yeah, I'm running a Linux box if that matters.

2. 3.156e7 is a double, which means the result will be a double too.
You might get better results if you print with &#37;f or the like. You can look up what you need to use for a double in a printf reference.

3. Code:
`printf("no, you are &#37;d.\n", age * 3.156e7);`
When you multiply an int by a double, for that is what "3.156e7" is, the int is promoted to a double. This follows C's integer promotion rules. http://www.thescripts.com/forum/thread524079.html

Basically, if two numbers of different types are used in the same expression, the result will be the type of the greater range.

Anyway, this means that your expression has a type of double. In order to print a double with printf(), you need to use %f instead of %d. That's it -- problem solved.

Side note: to scanf() doubles, you need %lf, not %f. %f handles floats for both functions. The reasons are a bit complicated . . . .

4. Code:
`printf("no, you are %d.\n", age * 3.156e7);`
You are telling printf that it should print an integer with the %d conversion specifier, HOWEVER you are supplying a double (a floating point format). printf will therefore display some bogus number, as you fed it the wrong data.
Although you declared age to be an int, it is converted by the compiler to a double because you multiply it with a double, being 3.156e7. The e7 makes it into a floating point number. So you have two options:
* either change the %d conversion specifier into %lf, so it will print the double
* change the 3.156e7 to an integer e.g. 3600 * 24 * 365

5. Thank you both for the quick help!! This solved the problem. Was I getting the wrong answer because the numbers were being represented as other numbers? Apparently I am not understanding this half as well as I thought I was... time to reread the chapter again!!

Thanks again!! You guys are awesome!!

6. Printf does not accept "&#37;lf". %f is one way to print a double, however.

Originally Posted by jimmy the saint
Thank you both for the quick help!! This solved the problem. Was I getting the wrong answer because the numbers were being represented as other numbers? Apparently I am not understanding this half as well as I thought I was... time to reread the chapter again!!

Thanks again!! You guys are awesome!!
Basically, yes. You were telling printf to print an integer, but gave it a floating number.
It's the same as handing an unknown document to someone and giving them wrong information as what it contains. Printf will reply on your judgment to know what type you passed and display it accordingly.

7. Mwaahaaa, so it isn't necessarily the size of the number, but the manner in which it is presented? I've got a long way to go... oh well, a journey of a thousand miles and all that!

8. * either change the &#37;d conversion specifier into %lf, so it will print the double
Actually -- no. printf() uses %f for both floats and doubles; scanf() differentiates and uses %f for floats and %lf for doubles.

Here's why. Both printf() and scanf() make use of variable argument lists. These are type-independent, because the compiler has no way of knowing what you might want to pass to the function. Thus, like unprototyped functions, the compiler promotes (more integral promotion!) any parameters to different types according to pre-defined rules when you call these functions.

One of these rules is that any float supplied by the programmer will actually be passed as a double. So printf() always sees doubles, whether you pass it floats or doubles. It only needs one flag to handle one data type -- %f.

scanf(), on the other hand, takes float* and double* pointers. Pointers are not subject to promotion, and so scanf() has to be told when it's getting a float* as opposed to when it's getting a double* -- and this needs two different flags. (It needs to know this because variable arguments are retrieved from the stack based on their size -- get too much and you'll have garbage, get too little and similar problems apply. floats and doubles are usually different sizes, so this is important.)

I told you the reasons were complicated.

 Typed too much . . . .

Mwaahaaa, so it isn't necessarily the size of the number, but the manner in which it is presented? I've got a long way to go... oh well, a journey of a thousand miles and all that!
Yes, C doesn't make things easy for you -- numbers can be represented in many, many different ways. There are a few basic types, like char, int, short and long -- along with floats and doubles for floating-point numbers, rather than integers. These are all (usually) different sizes and have different maximum and minimum values and (in the case of floats and doubles) precision. Then the integral types can be unsigned, which means you can't represent negative numbers, but you can represent positive numbers twice as large.

And then there's the trouble with floating point numbers not always being represented quite accurately . . . but that's another story. [/edit]

9. Originally Posted by jimmy the saint
Mwaahaaa, so it isn't necessarily the size of the number, but the manner in which it is presented? I've got a long way to go... oh well, a journey of a thousand miles and all that!
Well, that too.
Different types can be different sizes, so if you you pass a double (which you did) and tell printf it's an integer (which is half the size usually), then it also gives wrong information (and gives wrong information if you try to pass along more information to print as well!).

Welcome to C!

10. The section in this book that deals with these rules is a little over my head. Can any of you recommend a good resource that explains it in a simple "low speed" manner? I get the feeling if I don't get this, I'll soon hit a wall as far as learning to program!

11. To put this simply, there are two types of numbers: integers and floating point.
Integers are normal (non-decimal) numbers: eg, 1, 10, 1000, etc.
Floating point are decimal numbers: like 1.23, 4.978, etc.
If you do an operation with a floating point number, the result is always floating point.
So 1 * 1.5 = floating point, not integer. 1 / 1.5 = same thing. 1 + 1.5 = same thing. 1 - 1.5 = same thing. And so on.

So just remember that and pass the right type!
A better way might be to use a temporary variable first.

double d = 1 / 1.5;

If you did

int n = 1 / 1.5;

You would get a warning from the compiler (conversion from double to int), so you know you did something wrong!

Then just pass the right type to printf or other functions.

12. Hmm, well, you could try an online resource, such as this one: http://www.cplusplus.com/doc/tutorial/variables.html

Online tutorials tend to go even "faster" than books, however. If you're finding it difficult to understand, I would suggest getting another book.

But really, it's not that important right at the beginning. You just have to know about chars, ints, and doubles, for characters like 'a', numbers like 2, and floating-point numbers like 3.14 respectively. You can always look up the right format specifiers (like &#37;d or %f) if you forget which is which.

 Elysia keeps beating me! Must . . . type . . . faster! (Someone said that when I beat them to the post twice -- I forget who.) [/edit]

13. Thank you Elysia for that simple summary. In the dozen or so pages of explanation of data types, I didn't pick up on that simple concept. I'm sure that's a bit of a simplification, but that's exactly what I need at this point!

If I could give you all thank yous, like on the Ubuntu forums, I would, but since I can't Please accept my thanks here!! I think I'll be floating around this forum a lot in the near future!

14. dwks - I keep being beaten by everyone! I keep thanking everyone for their help, and by the time I post it, someone else has given great advice that deserves a thank you!! I need to set my typing on turbo-speed just keep up!

15. Well, one thing I might have left out is that there are 2 floating point types and 6 or so integer types, but that's not really important now.
So yeah, once you know the actual type, it's easy to check in the manual to know what type specifier to use.

Page 1 of 2 12 Last