首页 > 解决方案 > 为什么 uint64_t 不能正确显示 pow(2, 64) - 1?

问题描述

我试图理解为什么uint64_t类型不能pow(2,64)-1 正确显示。cplusplus 标准是 199711L。

我检查了pow()C++98 标准下的函数,即

double pow (double base     , double exponent);
float pow (float base      , float exponent);
long double pow (long double base, long double exponent);
double pow (double base     , int exponent);
long double pow (long double base, int exponent);

所以我写了下面的片段

double max1 = (pow(2, 64) - 1);
cout << max1 << endl;

uint64_t max2 = (pow(2, 64) - 1);
cout << max2 << endl;

uint64_t max3 = -1;
cout << max3 << endl;

输出是:

max1: 1.84467e+019
max2: 9223372036854775808
max3: 18446744073709551615

标签: c++floating-pointdoubleuint64

解决方案


浮点数具有有限的精度。

在您的系统上(通常假设 binary64 IEEE-754 格式)18446744073709551615不是具有double格式表示的数字。有表示的最接近的数字恰好是18446744073709551616

将两个幅度完全不同的浮点数相减(和相加)通常会产生错误。与较小的操作数相比,此错误可能很重要。在减法误差为1的情况下18446744073709551616. - 1. -> 18446744073709551616.,实际上与较小的操作数是相同的值。

当浮点值转换为整数类型,并且该值不能适合整数类型时,程序的行为是未定义的——即使整数类型是无符号的。


推荐阅读