Всякий раз, когда я вписываю возраст 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
В этой строке:
secondsLived = seconds*minutes*hours*days*years;
Вы умножаете число int
вместе, а затем вы назначаете результат uint_64
, Вычисление на int
с переполнения.
Приведите хотя бы одно из значений к uint_64
перед умножением их вместе, чтобы вычисление было сделано на uint_64
ценности:
secondsLived = (uint_64)seconds*minutes*hours*days*years;
secondsLived = seconds*minutes*hours*days*years;
Тот факт, что вы присваиваете результат uint64_t
не влияет на то, как это вычисляется.
поскольку seconds
, minutes
, hours
, days
, а также years
все целые числа со знаком, все вычисления выполняются в целых числах со знаком. Когда вы вводите большое количество лет, оно переполняется int
, Когда переполненный результат преобразуется в 64-разрядное целое число без знака, вы получаете очень большое число из-за способа представления отрицательных чисел в системе дополнения до двух.
Объявление любой из единичных переменных (скажем, years
) uint64_t
бы решить эту проблему:
int seconds = 60, minutes = 60, hours = 24, days = 365;
uint64_t years, secondsLived, secondsAwake;