uint64_t已错误地达到18446744071590568320



每当我输入65岁或以下的年龄时,我都会得到一个小于2100000的数字。然而,当我输入68岁或更高的年龄时,结果立即显示为18446744071590568320,这是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 secondsn",addCommas(secondsLived).c_str());
    printf("You have been awake for %s secondsn",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 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

在行中:

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

将多个int相乘,然后将结果分配给uint_64int上的计算溢出。

在将这些值相乘之前,至少将其中一个值强制转换为uint_64,以便对uint_64值进行计算:

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

将结果分配给uint64_t对其计算方式没有影响。

由于secondsminuteshoursdaysyears都是有符号整数,因此整个计算都是用有符号整数完成的。当您输入大量年份时,它会溢出int。当溢出的结果被转换为无符号64位整数时,由于负数在二的补码系统中的表示方式,您会得到一个非常大的数字。

声明uint64_t中的任何一个单元变量(比如years(都可以解决这个问题:

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

相关内容

  • 没有找到相关文章

最新更新