在不同的地方使用时在 c++ 中使用 pow() 的不同答案,尽管预期相同

different answers using pow() in c++ when used in different places, although same is expected

我展示了两段代码。我不太明白如何以不同方式使用 pow() 会导致这些代码有所不同。提前致谢。

在这道题中你要计算从 1 到 n 的所有整数的和,但是在 sum.For 的例子中你应该用负号来计算所有 2 的幂,对于 n⟉=⟩4 和等于- 1 -⟩2 + 3 -⟩4⟩=⟩-⟩4,因为1、2、4分别为20、21和22 分别。计算 n 的 t 个值的答案。

#include<bits/stdc++.h>    
typedef long long ll;
typedef double dl;
using namespace std;
int main() {
   ll n,t;

   ll i,cnt=0;
   cin>>t;
   while(t--)// for 't' number of test cases 
  {
       cin>>n;

           for(i=1,cnt=0;i<=n;i*=2,cnt++); //counting number of terms in the GP:1,2,4,....
           cout<<setprecision(20)<<((n*(n+1))/2)-(2*(pow(2,cnt)-1))<<endl;
  }
  return 0;

}
//output for above code:499999998352516352
// and the slightly modified code..


#include<bits/stdc++.h>
typedef long long ll;
typedef double dl;
using namespace std;
int main() {
    ll n,t;

    ll i,cnt=0;
    cin>>t;
    while(t--)// for 't' number of test cases
    {
    cin>>n;

    for(i=1,cnt=0;i<=n;i*=2,cnt++); 
    ll k=(pow(2,cnt)); //instead of directly printing the answer, 'k' is computed and then used to find the answer.
    cout<<setprecision(20)<<((n*(n+1))/2)-(2*(k-1))<<endl;
    }
    return 0;

}
//output for above code:499999998352516354
// the second one is the correct answer, the first one is wrong. how does pow() change the values here? 

显然给您带来麻烦的值是 n=1000000000,或 109。小于或等于该值的2的最大整数次幂为229。因此,您要计算的总和为 (10^9*(10^9+1))/2-2*(2^30-1),或 500000000500000000-2147483646,或 499999998352516354。

您的第二种方法可行,因为 2 的幂是精确的,并且因为您在减法中使用了整数运算。您的第一种方法失败了,因为该表达式被计算为双精度值。第一项 n*(n+1)/2 或 500000000500000000 是 "exact",这意味着浮点表示没有错误。第二项 2147483646 也是精确的。这种情况下的问题发生在减法上。两者之间的区别是不精确的,这意味着你失去了精度。

您没有理由使用 pow。您已经计算了 pow(2,cnt)。事实上,您根本不需要 cnt。只需使用

ll k;
for(k=1; k<=n; k*=2);