有没有更简单的方法来做到这一点?我怎样才能摆脱我的一个 while 循环?

Is there a simpler way to do this? How can I get rid of one of my while loops?

对于我的 CS 作业,我们被要求创建一个程序来使用 Viete's Formula 来近似圆周率。我已经这样做了,但是,我并不完全喜欢我的代码,并且想知道是否有一种方法可以在不使用两个 while 循环的情况下做到这一点。

(我的教授要求我们使用 while 循环,所以我想至少保留一个!)

#include <stdio.h>
#include <math.h>
#include <stdlib.h>

int main()
{
  double n, x, out, c, t, count, approx;
  printf("enter the number of iterations to approximate pi\n");
  scanf("%lf", &n);

  c = 1;
  out = 1;
  t = 0;
  count = 1;
  x = sqrt(2);

  while (count<=n)
  { 
      t=t+1;

      while (c<t)
      { 
          x=sqrt(2+x);
          c=c+1; 
      }

      out=out*(x/2);
      count=count+1; 
  }

  approx=2/out;
  printf("%lf is the approximation of pi\n", approx);
} 

我只是觉得我的代码可以以某种方式更简单,但我不确定如何简化它。

I just feel like my code could somehow be simpler, but I'm not sure how to simplify it.

I don't like the fact that I am using two while loops. I was wondering if there was a way to code this program using only one, rather than the two I am currently using

似乎只需要使用一个循环即可。

OP 的代码 while (c < t) loop 可以替换为 if (c < t) 并获得相同的结果。循环只执行 1 次或 0 次。通过调整初始ct,loop/block每次可以执行一次。从而完全否定测试。

Viete() 中进行了一些额外的调整。

#include <stdio.h>
#include <math.h>

double Viete(unsigned n) {
  const char *pi = "pi   3.141592653589793238462643383...";
  puts(pi);
  printf("m_pi=%.17f\n", acos(-1));
  double term = sqrt(2.0);
  double v = 1.0;
  while (n-- > 0) {
    v = v * term / 2;
    printf("v_pi=%.17f %u\n", 2 / v, n);
    term = sqrt(2 + term);
  }
  puts(pi);
  return 2 / v;
}

int op_pi(unsigned n) {
  unsigned c = 1;
  unsigned t = 0;
  unsigned count = 1;
  double out = 1;
  double x = sqrt(2);

  while (count <= n) {
    t = t + 1;

    // while (c < t) {
    // or 
    if (c < t) {
      x = sqrt(2 + x);
      c = c + 1;
    }

    out = out * (x / 2);
    count = count + 1;
    printf("%lf is the approximation of pi %u\n", 2 / out, count);
  }

  double approx = 2 / out;
  printf("%lf is the approximation of pi\n", approx);
}

int main(void) {
  op_pi(5);
  Viete(5);
}

输出

2.828427 is the approximation of pi 2
3.061467 is the approximation of pi 3
3.121445 is the approximation of pi 4
3.136548 is the approximation of pi 5
3.140331 is the approximation of pi 6
3.140331 is the approximation of pi
pi   3.141592653589793238462643383...
m_pi=3.14159265358979312
v_pi=2.82842712474618985 4
v_pi=3.06146745892071825 3
v_pi=3.12144515225805197 2
v_pi=3.13654849054593887 1
v_pi=3.14033115695475251 0
pi   3.141592653589793238462643383...

可以进行其他较小的简化。

考虑在外循环的每次迭代中内循环运行s的次数

  • 在第一次迭代中,它根本没有 运行 (c == t == 1)
  • 在每次后续迭代中,它 运行 恰好一次(因为自外循环的最后一次迭代以来 t 已递增一次)。

所以你可以用 if:

替换这个内部 while
    if (count > 1) {

一旦你这样做了,tc 就完全没有必要了,可以去掉。

如果您更改 x 的初始值(在循环之前),您可以让第一次迭代在这里计算它,从而也摆脱了 if。这留下了一个最小的循环:

out = 1;
count = 1;
x = 0;
while (count<=n) {
    x=sqrt(2+x);
    out=out*(x/2);
    count=count+1; 
}