为什么 cmath pow 给出不准确的答案?

Why does cmath pow give inaccurate answers?

在 C++11 中:

pow(1061,6);   // = 1426567426713180416

检查最后 3 位数字。 我确定结果是错误的,因为 1061^6 = 1426567426713180361.

但是另一种方法是正确的:

long a =1;    
for(int i=0; i<6 ; i++){ a*=1061; }
cout << a;  // = 1426567426713180361

pow 包含在 cmath 中。

如果有人知道,我想知道为什么两个结果不相等。

pow 使用 double 作为其输出,其精度约为 16 位小数。 64 位 long 但是有 19.

std::pow 适用于 double。对于如此大的整数值,它不像整数运算那样保持结果数的精度。

std::pow will return double for the integral case and this answer here 解释了第一个积分,其中 double 不能再精确地表示每个从 9007199254740993 开始的积分,此后我们可能有不能精确表示为 double 的整数。

我们可以更容易地看到这一点,因为使用统一初始化缩小转换是病式的。使用您想要的结果,我们看到:

double d2{1426567426713180361};

是缩小转换(live godbolt)

error: constant expression evaluates to 9007199254740993 which cannot be narrowed to type 'double' [-Wc++11-narrowing]
double d1{9007199254740993} ;
        ^~~~~~~~~~~~~~~~

因为无法准确表示。我们还可以看到前面的数字也是一个缩小转换:

double d1{9007199254740993} ;

同时:

double d3{1426567426713180416};

不是。