【问题标题】:Calculating Pi with C++; Where am I messing up?用 C++ 计算 Pi;我在哪里搞砸了?
【发布时间】:2015-12-26 22:32:49
【问题描述】:

为了好玩,我正在尝试使用众所周知的算法计算 pi: pi/4 = 1 - (1/3) + (1/5) - (1/7) + (1/9) 等等...... 然后将结果乘以 4 得到 pi(大约)。 我花了最后 45 分钟左右的时间编写并试图让这段代码工作。我在哪里搞砸了?任何帮助将不胜感激。

//I'm new, which of these are necessary in this program?
#include <iostream>
using namespace std;
#include <string>
#include <math.h>

int main()
{
//1.0 as 1/4 pi is used as part of the algorithm in the for loop
float pi_fourth = 1.0;
//to be used as a counter inside for loop
int i = 5;
//I want the for loop to stop after only a few iterations
for (pi_fourth = 1.000000; i < 20 ; i + 4)
{
    //algorithm for determining one-fourth pi
    // algorithm is pi/4 = 1 - 1/3 + 1/5 - 1/7 + 1/9, etc...
    (pi_fourth -= 1/i) += (1/(i-2));
}
//now to complete the program, I need to multiply result
//  of the for loop to get pi approx.
float real_pi = (pi_fourth * 4);
//final print statement to reveal pi to a few digits
cout << "pi is ABOUT " << endl << real_pi << endl;
return 0;
}

当它运行时,没有错误出现,它永远不会到达最终的打印语句,这让我相信这是一个无限循环。这是一个正确的假设吗?如果答案非常简单,我深表歉意;正如我之前提到的,我是 C++ 新手。

【问题讨论】:

  • for (pi_fourth = 1.000000; i &lt; 20 ; i + 4) i + 4 什么都不做,所以你有一个无限循环,因为 i 永远不会改变。
  • Clang: 警告:表达式结果未使用 [-Wunused-value]i + 4 下带有波浪线。
  • 从未见过这样的符号(pi_fourth -= 1/i) += (1/(i-2));,我想知道这是否有效。但是这里不适用整数除法吗?
  • @rekire,赋值表达式返回被赋值的事物,因此它是有效的。不过,它可能作为两个语句更具可读性。
  • 我从来没有高效地使用过 C++,所以我不是最好的人,但我会写成pi_fourth -= 1/(i*1.0) + 1/(i-2.0);

标签: c++ runtime-error infinite-loop pi


【解决方案1】:

我用cmets做了一个固定版本的程序:

#include <iostream>
// Only iostream is needed for cout and endl.
// using namespace std is usually not recommended on global scope

int main()
{
    float pi_fourth = 1.0;
    int i = 3;
    for(; i < 1000; i += 4)
    {
        // pi_fourth was already initialized. using 1.00000 instead of 1.0 has no effect.
        // i += 4 to add to i
        // fixed the algorithm, and wrote it in two statements.
        // 1.0/i instead of 1/i, otherwise it would be an integer division (because both 1 and i are integers).
        pi_fourth -= 1.0/i;
        pi_fourth += 1.0/(i + 2);
    }
    float real_pi = pi_fourth * 4.0;
    std::cout << "pi is ABOUT " << std::endl << real_pi << std::endl;
    return 0;
}

【讨论】:

  • @tmlen:非常感谢,您在短短几分钟内就教会了我很多东西!从 std(或任何其他“使用 X”)的工作原理来看,如何确保乘以浮点数而不是整数,以将结果保持为浮点数。
【解决方案2】:
for (pi_fourth = 1.000000; i < 20 ; i + 4)

i 它没有增加。试试

for (pi_fourth = 1.000000; i < 20 ; i += 4)

【讨论】:

  • 这很有帮助。至少现在这不是一个无限循环。这是我唯一不喜欢编程的地方。我的错误往往是完全愚蠢的。
【解决方案3】:

关于这件事的一些想法,与代码中的错误不太相关

在符号变化系列中,错误不超过最后一个丢弃的术语。因此,典型的方法是询问用户所需的精度,然后计算需要多少项的总和,表示为 N

应该从最小项到最大项进行求和,这样可以使舍入误差保持较小且可控。所以循环应该看起来像

for(int i = N; i > 0; i -= 2)

最好在每一个循环周期中添加一项,沿线某处

double sign = 1.0;
double pi = 0.0;
for(int i = N; i > 0; i -= 2) {
    auto term = sign / double(i);
    pi += term;
    sign = -sign;
}

return fabs(pi); // might be negative value

【讨论】:

    猜你喜欢
    • 2016-06-04
    • 2021-12-29
    • 1970-01-01
    • 2016-06-07
    • 2016-11-02
    • 1970-01-01
    • 2011-01-23
    • 1970-01-01
    • 2022-12-03
    相关资源
    最近更新 更多