使用循环估计具有系列扩展的PI

时间:2017-10-07 21:36:45

标签: java algorithm loops for-loop pi

我需要通过以下系列来估算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 .....,依此类推。

question也没有得到好的答案(估计没有真正的PI值)

6 个答案:

答案 0 :(得分:0)

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

  1. 首先忽略乘法4(或者你可以考虑它 每个学期)
  2. 考虑初始denom = 1,因此term = 1 / denom = 1
  3. 找到模式。请注意,每一步newTerm = (-1)*(1/(denom+2))。所以在每次迭代时,都要更新sum和denom 相应地。
  4. 在n次迭代之后,只需将总和与4
  5. 相乘

答案 1 :(得分:0)

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);
    }

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

答案 2 :(得分:0)

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);
}

答案 3 :(得分:0)

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

  1. 首先,您应该只将一个加数除以 public function __constrcut(){ //changing language accordding to session $this->middleware(function($request,$next){ app::setLocale(Session::get('locale')); return $next($request); }); ,将另一个加到i,而不是i + 2
  2. 您为每个加号添加i + 2,这是错误的,它应该像1而不是1 / sum
  3. 如果您决定在一个迭代步骤中创建两个加号,则1 - (1 / sum)需要在每个步骤i甚至i+2中前进更多
  4. 如果i+4变大,您可以快速达到intdouble精度的限制,您可能需要nBigInteger来提供无限精度的空间成本。
  5. 您目前正在制作的系列如下:

    BigDecimal

    这应该是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)。但这样可能更容易理解。

答案 4 :(得分:0)

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

  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;
}

答案 5 :(得分:0)

这只是函数式编程中的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);