carljalal
carljalal

Reputation: 647

uint64_t has incorrectly reached 18,446,744,071,590,568,320

Whenever I input an age of 65 or less, I get a number somewhere less than 2,100,000. However, when I input an age of 68 or higher, the result is instantly put at 18,446,744,071,590,568,320, which is the maximum value for uint64_t. I have no idea why there is this jump in results. It works fine all the way until about 2,100,000.

// How many seconds have I lived?
#include <stdio.h>
#include <string>
#include <cstdint>
using namespace std;
string addCommas(uint64_t answer);
int main ()
{
    int seconds = 60, minutes = 60, hours = 24, days = 365;
    int years; uint64_t secondsLived, secondsAwake;
    printf("How many years have you lived? ");
    scanf("%d",&years);
    secondsLived = seconds*minutes*hours*days*years;
    secondsAwake = (float)secondsLived*0.666;

    printf("\nYou have existed for %s seconds\n",addCommas(secondsLived).c_str());
    printf("You have been awake for %s seconds\n",addCommas(secondsAwake).c_str());
}
string addCommas(uint64_t answer){
    string num = to_string(answer);
    int insertplace = (int)num.length() - 3;
    while (insertplace > 0) {
        num.insert(insertplace, ",");
        insertplace-=3;
    }
    return num;
}

Here are a couple outputs:

How many years have you lived? 67

You have existed for 2,112,912,000 seconds
You have been awake for 1,407,199,392 seconds


How many years have you lived? 69

You have existed for 18,446,744,071,590,568,320 seconds
You have been awake for 12,285,531,553,090,562,048 seconds

Upvotes: 0

Views: 175

Answers (3)

Sergey Kalinichenko
Sergey Kalinichenko

Reputation: 727077

Since seconds, minutes, hours, days, and years are all signed integers, the entire computation is done in signed integers. When you enter a large number of years, it overflows int. When the overflown result gets converted to unsigned 64-bit integer, you get a very large number because of the way that negative numbers are represented in two's complement system.

Declaring any of the unit variables (say, years) a uint64_t would fix this problem:

int seconds = 60, minutes = 60, hours = 24, days = 365;
uint64_t years, secondsLived, secondsAwake;

Upvotes: 2

Jesper
Jesper

Reputation: 207006

In this line:

secondsLived = seconds*minutes*hours*days*years;

You are multiplying a number of ints together and then you assign the result to the uint_64. The computation on ints overflows.

Cast at least one of the values to uint_64 before multiplying them together, so that the computation is done on uint_64 values:

secondsLived = (uint_64)seconds*minutes*hours*days*years;

Upvotes: 4

David Schwartz
David Schwartz

Reputation: 182883

secondsLived = seconds*minutes*hours*days*years;

The fact that you assign the result to a uint64_t has no effect on how it's computed.

Upvotes: 3

Related Questions