Pi的数值评估

时间:2013-11-26 18:42:20

标签: c

我想通过运行以下代码来近似评估Pi,该代码适合具有单位直径的圆内的n个边的正多边形,并使用代码中的函数计算其周长。但是,当使用长双变量类型时,第34项之后的输出为0,或者当使用双变量类型时,输出无边界地增加。我该如何解决这种情况?任何建议或帮助表示赞赏和欢迎。

由于

P.S:操作系统:Ubuntu 12.04 LTS 32位,编译器:GCC 4.6.3

#include <stdio.h>
#include <math.h>
#include <limits.h>
#include <stdlib.h>
#define increment 0.25
int main()
{
    int i = 0, k = 0, n[6] = {3, 6, 12, 24, 48, 96};
    double per[61] = {0}, per2[6] = {0};

    // Since the above algorithm is recursive we need to specify the perimeter for n = 3;
    per[3] = 0.5 * 3 * sqrtl(3);
    for(i = 3; i <= 60; i++)
    {
        per[i + 1] = powl(2, i) * sqrtl(2 * (1.0 - sqrtl(1.0 - (per[i] / powl(2, i)) * (per[i] / powl(2, i)))));
        printf("%d      %f \n", i, per[i]);
    }
    return 0;
    for(k = 0; k < 6; k++)
    {
        //p[k] = k
    }
}

2 个答案:

答案 0 :(得分:2)

一些想法:

使用y = (1.0 - x)*( 1.0 + x)代替y = 1.0 - x*x。这有助于1阶段“减去几乎相等的值”,但我仍然坚持下一个1.0 - sqrtl(y)y接近1.0。

// per[i + 1] = powl(2, i) * sqrtl(2 * (1.0 - sqrtl(1.0 - (per[i] / powl(2, i)) * (per[i] / powl(2, i)))));
long double p = powl(2, i);
// per[i + 1] = p * sqrtl(2 * (1.0 - sqrtl(1.0 - (per[i] / p) * (per[i] / p))));
long double x = per[i] / p;
// per[i + 1] = p * sqrtl(2 * (1.0 - sqrtl(1.0 - x * x)));
// per[i + 1] = p * sqrtl(2 * (1.0 - sqrtl((1.0 - x)*(1.0 + x)) ));
long double y = (1.0 - x)*( 1.0 + x);
per[i + 1] = p * sqrtl(2 * (1.0 - sqrtl(y) ));

更改数组大小或for()

double per[61+1] = { 0 };  // Add 1 here
...
for (i = 3; i <= 60; i++) {
  ...
  per[i + 1] = 

以下是pi的类似方法

unsigned n = 6;
double sine = 0.5;
double cosine = sqrt(0.75);
double pi = n*sine;
static const double mpi = 3.1415926535897932384626433832795;
do {
  sine = sqrt((1 - cosine)/2);
  cosine = sqrt((1 + cosine)/2);
  n *= 2;
  pi = n*sine;
  printf("%6u s:%.17e c:%.17e  pi:%.17e %%:%.6e\n", n, sine, cosine, pi, (pi-mpi)/mpi);
} while (n <500000);

答案 1 :(得分:1)

从接近1.0的数字中减去1.0导致“灾难性的取消”,其中FP计算中的相对误差由于有效数字的丢失而急剧上升。尝试为0到60之间的每个i评估pow(2, i) - (pow(2, i) - 1.0),你会看到我的意思。

此问题的唯一真正解决方案是重新组织方程式以避免减去几乎相等的非零量。有关详细信息,请参阅Acton, Real Computing Made Real 或Higham,数值算法的准确性和稳定性