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

时间:2018-11-05 17:58:52

标签: c++ c++11 cmath

在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

战俘中包括战俘。

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

3 个答案:

答案 0 :(得分:2)

pow的输出使用double,其精度约为16个十进制数字。 64位的long有19。

答案 1 :(得分:1)

std::pow将返回整数情况下的double,而此answer here解释了第一个整数,其中double不再能够精确地表示每个以9007199254740993开头的整数,之后我们可能会有整数不能完全代表两倍。

我们可以使用以下事实更容易地看到这一点:使用统一的初始化会缩小转换的范围。使用您想要的结果,我们看到:

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};

不是。

答案 2 :(得分:0)

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