Math coming out incorrectly?

When I run this code timeleft always comes out to a weird negative number for example when age is 15 timeleft evaluates to -1928147296. How can I fix this?

1
2
3
4
5
6
7
8
9
10
11
12
13
#include <iostream>
#include <string>
using namespace std;

int main()
{
int age;
cout << "How old are you?" << endl;
cin >> age;
int timeleft = (90-age)*31557600;
cout << "Well make every second count because you probably have about " << timeleft << " seconds left to live...";
}
int generally only holds 32 bits (including a sign bit).

int has a range of:
-2,147,483,648 to 2,147,483,647

If you go out of these bounds, then you've exceeded the number of bits available. You have two options:
1) Use a long long which is 64 bits and has a range of:
–9,223,372,036,854,775,808 to 9,223,372,036,854,775,807
2) Use a floating point number (float/double).
This has a massive range, at the cost of resolution. It's sort of like scientific notation in that you could have 1.23 x108 which rounds off anything small.
Althogh that was an issue it was not the problem with the math. (90-age)*31557600 is still evaluating to an incorrect value. Even if I replace timeleft in the cout line with the equation it still evaluates wrong.
Last edited on
Looks like an integer overflow.
An "overflow" is typically when you try to store more information than there is space for.
In this case, int is not "wide" enough to hold the value of:

(90 - 15) * 31,557,600 = 2,366,820,000

Wikipedia wrote:
−2,147,483,648 to +2,147,483,647


http://en.wikipedia.org/wiki/Integer_%28computer_science%29#Common_long_integer_sizes

One solution would be to use uint64_t instead of int, as in:

1
2
3
4
5
6
7
8
#include <cstdint>

// ...

std::uint64_t age;
cout << "How old are you?" << endl;
cin >> age;
std::uint64_t timeleft = (90ull - age) * 31557600ull;


Another solution would be to use a arbitrary precision arithmetic ("BigNum") library.
A lot of newer languages have such a library built-in, C++ does not:

http://en.wikipedia.org/wiki/Arbitrary-precision_arithmetic
https://gmplib.org/

ninjazrb wrote:
Althogh that was an issue it was not the problem with the math. (90-age)*31557600 is still evaluating to an incorrect value.

By default, the type of integer literals is int.
So the type of (90-age)*31557600 will be int if age is int as well. So it will overflow.

Add suffixes to the literals to mark them as unsigned (long long) int's, as in the example above.

Edit: mistake in code.
Last edited on
Topic archived. No new replies allowed.