# Thread: Short program overflow issue?

1. ## Short program overflow issue?

There is a question in my text C Primer + that wants you to convert your age into seconds and it tells you that there are 3.156x(10 to the power of seven) seconds in a year. So I came up with the following program which produces the same output for every age. From that I a can see that I messed up. Can anyone see where I went wrong? My guess is that a long double isn't big enough to hold that no. of seconds.

Code:
```/* convert age from years to seconds */
#include <stdio.h>
int main(void)
{
int age;
long double seconds_age;

seconds_age = age * 3.156e7;
scanf("%d", &age);

printf("%d years is %lf seconds", age, seconds_age);
}```

2. Code:
`seconds_age = age * 3.156e7;`
This is not an equation. It takes the current value of age times 3.156e7 and puts it into seconds_age. In other words, you need to know age BEFORE you make this assignment.

3. Now, that I have posted I think I know my mistake. The statement order was wrong. I should have put the seconds_age = age * 3.156e7; after the scanf. Because I didn't the printf is reading seconds_age as an undeclared variable and producing garbage. I am just guessing though.

4. Originally Posted by NeonBlack
In other words, you need to know age BEFORE you make this assignment.
Thanks. Just figured that out while you were posting. It makes sense of course.

5. You are quite optimistic as to how old you're going to get.

The float data type is guaranteed to be able to hold at least 3.40282347E+38, which corresponds to about 10^30 years.
Are you sure you need a long double? :-)

--
Computer Programming: An Introduction for the Scientifically Inclined

6. God might use the program

Incidentally, 3.156e7 is a double literal. 3.156e7L (or 3.156e7l) is the corresponding long double literal.

7. You don't, in fact, need a double at all. An int should be big enough, otherwise use a long. You should avoid using floats and doubles wherever possible. Computers cannot accurately represent decimal places (especially, repeating patterns like 1/3), so they are approximated. This can sometimes lead to problems where you store 1.0 in a float, but it gets printed as .999999999999

QuantumPete

8. Thanks for the feedback. I do hope to live for a long time but I agree. It's probably longer than I need.

9. You don't, in fact, need a double at all. An int should be big enough, otherwise use a long.
A long may not be long enough, since long is only guaranteed an upper bound of 2147483647, and many people live for more seconds than that. An unsigned long, on the other hand, would cut it, at least for now (though I have read of unsubstantiated claims of people living as long as 150 years).

You should avoid using floats and doubles wherever possible.
I agree.

Computers cannot accurately represent decimal places (especially, repeating patterns like 1/3), so they are approximated. This can sometimes lead to problems where you store 1.0 in a float, but it gets printed as .999999999999
That said, I believe 1.0 can be accurately and precisely represented in most, if not all, floating point representations, including IEEE 754.

10. Originally Posted by QuantumPete
Computers cannot accurately represent decimal places (especially, repeating patterns like 1/3), so they are approximated.
Really? I find that hard to believe.
No, I suspect it's the way it is to gain reasonable range for floats and doubles while still maintaining a relatively low space requirement for the variables.
More likely, it's the IEE standard which makes it difficult to represent non-approximated numbers.

11. Originally Posted by QuantumPete
You don't, in fact, need a double at all. An int should be big enough, otherwise use a long. You should avoid using floats and doubles wherever possible. Computers cannot accurately represent decimal places (especially, repeating patterns like 1/3), so they are approximated. This can sometimes lead to problems where you store 1.0 in a float, but it gets printed as .999999999999
This story is often told to children to scare them away from floats, but it's really not so bad. If you do

Code:
`float f = 1.0;`
then f will contain exactly 1, and you can safely cast it to integer. However, if you do

Code:
```float f = 1.0;
f = f/3;
f = f*3;```
(assuming a compiler won't be bold enough so as to optimize away this code) then f will indeed be slightly below 1, and casting it to an integer will yield zero.

As long as the value you store in a float will "fit" within the mantissa (i.e. the decimal point doesn't float :-) ) it will still be exact.

--
Computer Programming: An Introduction for the Scientifically Inclined

12. Really? I find that hard to believe.
No, I suspect it's the way it is to gain reasonable range for floats and doubles while still maintaining a relatively low space requirement for the variables.
More likely, it's the IEE standard which makes it difficult to represent non-approximated numbers.
No, QuantumPete is correct on that point. Take the example of 1/3. If you attempt to precisely express that in decimal, you will find that you eventually get bored of writing 3s, as in 0.333333333333... Likewise, precisely expressing 1/3 in binary has the same problem. You could, however, precisely express 1/3 in base 3, namely as 10, but then you would have problems precisely expressing other numbers in base 3.

13. 1/3 is an obvious problematic number, but floats have additional approximation problems due to that they're basically base raised to an exponent IIRC.
They could use 8 bytes for base and 8 bytes for floating part and you would be able to represent a lot of numbers with exact precision. But it might be a waste of space...

14. Actually, floating point numbers consist of a sign, a mantissa (not "base", but number betwee 0.0 and 1.0 expressed in base 2), and an exponent. The actual number is then sign * mantissa * 2 ^ exponent.

Since the mantissa has a limited number of bits (for example 24 or 53 for float and double in IEEE-754), there is a limit to how precisely we can describe numbers that are infinitely repeating when expressed in base 2. 1/3 in base 3, as explained, is a precise value of 0.1(3), just like 1/2 in base 2 is 0.1. Decimal [base 10] 0.1 can not be described precisely in binary, nor can any other number that is a even power of 2 multiple of 0.1 (e.g. 0.2, 0.4, 0.8, 1.6). If the number is a power of 2 + (0.1 * power of 2), then it's also going to be an endless sequence.

--
Mats

15. Originally Posted by laserlight
You could, however, precisely express 1/3 in base 3, namely as 10, but then you would have problems precisely expressing other numbers in base 3.
10 in base 3 is 3, not 1/3, right?