uint64_t неправильно достиг 18,446,744,071,590,568,320

Всякий раз, когда я вписываю возраст 65 или меньше, я получаю число где-то менее 2100000. Тем не менее, когда я ввожу возраст 68 лет или старше, результат мгновенно оценивается в 18 446 744 071 590 568 320, что является максимальным значением для uint64_t. Я понятия не имею, почему происходит такой скачок в результатах. Он прекрасно работает до 2100000.

// 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;
}

Вот пара выходов:

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 secondsHow 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

0

Решение

В этой строке:

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

Вы умножаете число intвместе, а затем вы назначаете результат uint_64, Вычисление на intс переполнения.

Приведите хотя бы одно из значений к uint_64 перед умножением их вместе, чтобы вычисление было сделано на uint_64 ценности:

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

Другие решения

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

Тот факт, что вы присваиваете результат uint64_t не влияет на то, как это вычисляется.

3

поскольку seconds, minutes, hours, days, а также years все целые числа со знаком, все вычисления выполняются в целых числах со знаком. Когда вы вводите большое количество лет, оно переполняется int, Когда переполненный результат преобразуется в 64-разрядное целое число без знака, вы получаете очень большое число из-за способа представления отрицательных чисел в системе дополнения до двух.

Объявление любой из единичных переменных (скажем, years) uint64_t бы решить эту проблему:

int seconds = 60, minutes = 60, hours = 24, days = 365;
uint64_t years, secondsLived, secondsAwake;
2
По вопросам рекламы [email protected]