为什么 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};
不是。
在 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};
不是。