繁体   English   中英

使用循环使用系列扩展估算PI

[英]Estimate PI with series expansion using loops

我需要通过执行以下系列估算PI:

m(i) = 4( 1- 1/3 + 1/5 - 1/7 + 1/9 - 1/11 ...)

到目前为止,这是我所做的:

 float mOfI = 1;
    System.out.println("i \t \t \t \t  m(i)" );
    for (int i = 1; i < n; i++) {
        float sum = i + 2;
        mOfI += 4 * (1 - (1 / sum));
        mOfI -= 4 * (1 - (1 / sum));
        System.out.println(i + "\t \t \t \t" +mOfI);
    }

我知道我在这里缺少很多规则,但是如何使它正常工作? 我的意思是数学逻辑。 如何正确解决?

请注意系列中的-+ ,所有数字均为奇数,因此我无法使用i%2

估计的PI可能是4.0000 , 3.1515, 3.1466 .....等等。

同样,这个问题没有得到很好的答案(没有估计的实际PI值)

简单点,找到容易的模式。 这是一个提示

  1. 首先忽略4的乘法(或者您可以在每一项中考虑它)
  2. 考虑初始定理= 1,因此项= 1 / denom = 1
  3. 找到图案。 请注意,每一步newTerm = (-1)*(1/(denom+2)) 因此,在每次迭代时,都要相应地更新总和和标称值。
  4. n次迭代后,将和乘以4
float m = 4;
    for (int i = 1; i < n; i++) {
        if(i%2==0){
           m +=4/(2*i+1);
        } else {
           m -=4/(2*i+1);
        }
        System.out.println(i + "\t \t \t \t" +m);
    }

注意:我在移动应用程序上,可能存在语法错误,但是您应该明白这一点。

mOfI永远不会改变,因为这两行相互抵消

    mOfI += 4 * (1 - (1 / sum));
    mOfI -= 4 * (1 - (1 / sum));

尝试这个。

double mOfI = 4.0;
System.out.println("i \t \t \t \t  m(i)" );
for (int i = 1, d = 3, s = -1;
         i < n; 
         i++, d += 2, s = -s) {
    mOfI += 4.0 / (s * d);
    System.out.println(i + "\t \t \t \t" +mOfI);
}

您的代码中存在多个问题。

  1. 首先,您只应将一个被除以i并将另一个除以i + 2 ,而不能同时除以i + 2
  2. 您对每个被加数加1 ,这是错误的,它应该像1 / sum而不是1 - (1 / sum)
  3. 接下来,如果您决定在一个迭代步骤中同时创建两个求和项,那么i需要在每个步骤( i+2甚至i+4提高更多
  4. 如果n变大,则可以很快达到intdouble precision的极限,您可能需要BigIntegerBigDecimal ,它们可以提供无限的空间成本精度

您当前正在制作的系列看起来像:

4 * ((1 - 1 / 1) - (1 - 1 / 1) + (1 - 1 / 2) - (1 - 1 / 2) +- ...)

由于每个部分相互抵消,因此应为0


正确的版本如下所示:

double result = 0;

// Whether we add or subtract the summand
boolean doAdd = true;
// Start at i = 0 to produce 1 as first denominator,
// else use - instead of + in the code
for (int i = 0; i < n; i++) {
    // Advance in steps of 2 and use odd values
    // Denominator will be 1, 3, 5, 7, ... for i = 0, 1, 2, 3, ...
    double summand = 1 / (2 * i + 1);

    if (doAdd) {
        // Add it
        result += summand;
    } else {
        // Subtract it
        result -= summand;
    }
    // Toggle the flag
    doAdd = !doAdd;
}

// Multiply by 4
result *= 4;

当然,如前所述,您可能需要用BigDecimal代替。

如果您不想使用额外的标志,也可以使用if (i % 2 == 0)代替if (doAdd) 但是那样一来,它可能更容易理解。

感谢您的宝贵时间,但我得到了正确的解决方案:

  double start = 1;         // Start series
    double end   = 901;     // End series
    System.out.println("\ni           m(i)     ");
    System.out.println("---------------------");
    for (double i = start; i <= end; i += 100) {
        System.out.printf("%-12.0f", i);
        System.out.printf("%-6.4f\n", estimatePI(i));
    }
}

/** Method estimatePI */
public static double estimatePI(double n) {
    double pi = 0;      // Set pi to 0
    for (double i = 1; i <= n; i ++) {
        pi += Math.pow(-1, i +1) / (2 * i - 1);
    }
    pi *= 4;
    return pi;
}

这只是函数式编程中的Java 9练习。 您可以使用此行计算PI:

double pi = 4 * Stream.iterate(1.0, i -> i < 10000000, i -> i + 2)
            .reduce(0.0, (a, d) -> ((d - 1) / 2) % 2 == 0 ? (a + 1 / d) : (a - 1 / d));

Java 8和Java 9示例:

// Java 9
double pi = 4 * Stream.iterate(1.0, i -> i < 10000000, i -> i + 2)
        .reduce(0.0, (a, d) -> ((d - 1) / 2) % 2 == 0 ? (a + 1 / d) : (a - 1 / d));
System.out.println(pi);
// Java 8
pi = 4 * Stream.iterate(1.0, i -> i + 2).limit(10000000)
        .reduce(0.0, (a, d) -> ((d - 1) / 2) % 2 == 0 ? (a + 1 / d) : (a - 1 / d));
System.out.println(pi);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM