【问题标题】:Loss of precision when using pow in C++在 C++ 中使用 pow 时精度损失
【发布时间】:2015-04-22 03:31:25
【问题描述】:

10^1.64605 = 44.2639330165

但是在 C++ 中使用 pow:

double p = pow(10,1.64605) returns 44.2641. 

有没有办法提高这里的精度?我尝试将双方都转换为long double,但这也无济于事。

更有趣的是:

cout<<p;
double a = -1.64605;
cout<<pow(10,-a);
p = pow(10, (-p));
cout<<p;

输出是:

-1.64605
44.2639
44.2641

为什么?

【问题讨论】:

  • 除了使用 Bignum 库之外,可能没有什么可以让它变得更好。
  • 当得到 44.2641 你用什么来显示它?调试器?考特?打印?
  • 尝试添加 #include 然后 cout
  • 您使用的是哪个编译器/操作系统?在输出上使用 setprecision 调用时,我最终得到 44.26393302。
  • 正在做: printf("%.12f\n",pow(10,1.64605));我得到:44.263933016536

标签: c++ precision pow


【解决方案1】:

cout 正在截断您的双精度以进行显示,但pow 计算的值可能至少与您预期的一样精确。有关如何在控制台中获得更精确的显示,请参阅:

How do I print a double value with full precision using cout?

鉴于大卫的催促,我会详细说明。

您说double p = pow(10,1.64605) returns 44.2641,但这是不正确的。它返回 44.26393301653639156;如果没有任何格式说明符,它将显示为 44.2639(您稍后会看到)。

当您在第二个代码片段中 cout p 的原始值时,它会显示 -1.64605(由于精度降低格式)并且您假设它是 正好是 -1.64605,而它实际上介于 -1.64605115... 和 -1.64605213... 之间,确实在表达式 cout &lt;&lt; pow(10, (-p));

中计算为 44.2641

【讨论】:

  • 这只是表面上的划痕,但并没有真正深入问题的根源。例如,亲自查看cout &lt;&lt; pow(10,1.64605) 的输出,即使是完全精确的。
  • 我不确定你在说什么。如果您说的是44.2641,他显然只是在发布时混淆了他的程序结果。
  • 不,他没有。解释与我的回答中描述的完全一样。
  • 我的意思是他写的44.2641是他最初计算的结果,而实际上是他第二次计算的结果。
  • 错了。 pow(10,1.64605) 返回 44.2639。返回 44.2641 的是 pow(10, (-p))。这就引出了p 是什么值的问题。这一切都在我的回答中进行了解释。
【解决方案2】:

通过检查p 可以找到答案。您没有显示它是如何初始化的。

您会发现p != a,尽管当您将它们打印到控制台时它们看起来是相同的。当您打印到控制台时,您只打印了前 6 个有效十进制数字。以更高的精度打印这两个值,您会发现它们不相等。

你说过:

double p = pow(10,1.64605);

计算为44.2641。但事实并非如此。如果您实际执行该代码,您将看到它。

double p = pow(10,1.64605);
cout << p;

输出44.2639

您的代码与上面的代码略有不同。它是:

cout << p;
p = pow(10, (-p));
cout << p;

p 的原始值输出为全精度,所有内容都会显示出来。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-12-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-26
    • 1970-01-01
    • 1970-01-01
    • 2014-07-13
    相关资源
    最近更新 更多