【长 PI】

/*
长 PI 

说明:
圆周率后的小数位数是无止境的,如何使用电脑来计算这无止境的小数是一些数学家与程式设计师所感兴趣的,在这边介绍一个公式配合 大
数运算,可以计算指定位数的圆周率。

解法 :
首先介绍J.Marchin的圆周率公式:
    PI = [16/5 - 16 / (3*5^3 ) + 16 / (5*5^5) - 16 / (7*5^7) + ] ......] -
        [4/239 - 4/(3*239^3) + 4/(5*239^5) - 4/(7*239^7) + ......]
可以将这个公式整理为:
    PI = [16/5 - 4/239] - [16/(5^3)- 4/(239^3)]/3+  [16/(5^5)- 4/(239^5)]/5 + ......
也就是说第n项,若为奇数则为正数,为偶数则为负数,而项数表示方式为:
    [16/5^(2*n-1)- 4/239^(2*n-1)] / (2*n-1)
如果我们要计算圆周率至10的负L次方,由于[16/5^(2*n-1) - 4/239^(2*n-1)]中16/5^(2*n-1) 比4/239^(2*n-1) 来的大,具有决定性,所以表示
至少必须计算至第n项:
    [16/5^(2*n-1)] / (2*n-1) = 10^(-L)
将上面的等式取log并经过化简,我们可以求得:
    n = L / (2log5) = L /  1.39794
所以若要求精确度至小数后L位数,则只要求至公式的第n项,其中n等于:
    n = [L/1.39794] + 1
在上式中[]为高斯符号,也就是取至整数(不大于L/1.39794 的整数);为了计简方便,可以在 程式中使用下面这个公式来计简第n项:
    [W(n) -1/5^2 - V(n) - 1 / (239^2)] / (2*n-1)
这个公式的演算法配合大数运算函式的演算法为:
    div(w, , 25,  w);
    div(v, , 239,  v);
    div(v, , 239,  v);
    sub(w, , v,  q);
    div(q, , 2*k-1,  q)
至于大数运算的演算法,请参考之前的文章,必须注意的是在输出时,由于是输出阵列中的整数值,如果阵列中整数位数不满四位,则必须补
上0,在C语言中只要 使用格式指定字%04d ,使得不足位数部份自动补上0再输出,至于Java的部份,使用 NumberFormat来作格式化

*/

#include <stdio.h>

#define L 1000                //L为位数,N是array的长度
#define N L/4 + 1

void add(int* , int* , int* );
void sub(int* , int* , int* );
void div(int* , int , int* );

int main(void)
{
    int s[N+3] = {0};
    int w[N+3] = {0};
    int v[N+3] = {0};
    int q[N+3] = {0};
    int n = (int)(L/1.39793 + 1);
    int k;

    w[0] = 16*5;
    v[0] = 4*239;

    for(k = 1; k <= n; k++)
    {
        div(w, 25, w);
        div(v, 239, v);
        div(v, 239, v);
        sub(w, v, q);
        div(q, 2 * k - 1, q);

        if(k % 2)
        {
            add(s, q, s);
        }
        else
        {
            sub(s, q, s);
        }
    }
    printf("%d", s[0]);
    for(k = 1; k < N; k++)
    {
        printf("%04d", s[k]);
    }
    printf("\n");

    return 0;
}

void add(int* a, int* b, int* c)
{
    int i, carry = 0;

    for(i = N + 1; i >= 0; i--)
    {
        c[i] = a[i] + b[i] + carry;
        if(c[i] < 10000)
        {
            carry = 0;
        }
        else
        {
            c[i] = c[i] - 10000;
            carry = 1;
        }
    }
}

void sub(int* a, int* b, int*c)
{
    int i, borrow = 0;
    for(i = N + 1; i >= 0; i--)
    {
        c[i] = a[i] - b[i] -borrow;
        if(c[i] >= 0)
        {
            borrow = 0;
        }
        else
        {
            c[i] = c[i] + 10000;
            borrow = 1;
        }
    }
}

void div(int* a, int b, int* c)
{
    int i, tmp, remain = 0;
    for(i = 0; i <= N + 1; i++)
    {
        tmp = a[i] + remain;
        c[i] = tmp / b;
        remain = (tmp % b) * 10000;
    }
}

结果如下:

时间: 2024-07-31 14:26:50

【长 PI】的相关文章

长PI

由于作者不习惯该编辑器,只是贴出上本文的截图,详见:https://www.yuque.com/docs/share/98626bcf-dc61-4555-b623-8b0adc495fb7 原文地址:http://blog.51cto.com/4754569/2325810

java 经典算法(转)

1.河内之塔.. 2.Algorithm Gossip: 费式数列. 3. 巴斯卡三角形 4.Algorithm Gossip: 三色棋 5.Algorithm Gossip: 老鼠走迷官(一) 6.Algorithm Gossip: 老鼠走迷官(二) 7.Algorithm Gossip: 骑士走棋盘 8.Algorithm Gossip: 八皇后 9.Algorithm Gossip: 八枚银币. 10.Algorithm Gossip: 生命游戏. 11.Algorithm Gossip:

【经典算法大全】收集51种经典算法 初学者必备

<经典算法大全>是一款IOS平台的应用.里面收录了51种常用算法,都是一些基础问题.博主觊觎了好久,可悲哀的是博主没有苹果,所以从网上下了老奔的整理版并且每个都手敲了一遍. 虽然网上也有博客贴了出来,但是自己写写感觉总是好的.现在分享个大家. 代码和运行结果难免有出错的地方,请大家多多包涵. 1.河内之塔(汉诺塔) 2.费式数列 3.巴斯卡三角形 4.三色棋 5.老鼠走迷宫(1) 6.老鼠走迷宫(2) 7.骑士走棋盘 8.八皇后 9.八枚银币 10.生命游戏 11.字串核对 12.双色河内塔,

经典算法大全

原文地址:经典算法大全 作者:liurhyme 经                                                                    典                                                                    算                                                                    法                  

java学习-4 经典算法

1.河内之塔.. 2.Algorithm Gossip: 费式数列. 3. 巴斯卡三角形 4.Algorithm Gossip: 三色棋 5.Algorithm Gossip: 老鼠走迷官(一) 6.Algorithm Gossip: 老鼠走迷官(二) 7.Algorithm Gossip: 骑士走棋盘 8.Algorithm Gossip: 八皇后 9.Algorithm Gossip: 八枚银币. 10.Algorithm Gossip: 生命游戏. 11.Algorithm Gossip:

POJ-2533最长上升子序列(DP+二分)(优化版)

Longest Ordered Subsequence Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 41944   Accepted: 18453 Description A numeric sequence of ai is ordered if a1 < a2 < ... < aN. Let the subsequence of the given numeric sequence (a1, a2, ...

POJ 2774 Long Long Message &amp;&amp; URAL 1517. Freedom of Choice(求最长重复子序列)

两个题目意思差不多,都是让求最长公共子串,只不过poj那个让输出长度,而URAL那个让输出一个任意的最长的子串. 解体思路: Long Long Message Time Limit: 4000MS   Memory Limit: 131072K Total Submissions: 22313   Accepted: 9145 Case Time Limit: 1000MS Description The little cat is majoring in physics in the cap

raspberry pi 上使用 MQ-7一氧化碳传感器模块

MQ-7一氧化碳传感器模块介绍 简要说明: 一. 尺寸:32mm X22mm X27mm   长X宽X高 二. 主要芯片:LM393.MQ-7气体传感器 三. 工作电压:直流5伏 四. 特点: 1.具有信号输出指示. 2.双路信号输出(模拟量输出及TTL电平输出) 3.TTL输出有效信号为低电平.(当输出低电平时信号灯亮,可直接接单片机) 4.模拟量输出0~5V电压,浓度越高电压越高. 5.对一氧化碳具有很高的灵敏度和良好的选择性. 6.具有长期的使用寿命和可靠的稳定性 五.应用: 用于家庭.环

POJ 3261 Milk Patterns 后缀数组求 一个串种 最长可重复子串重复至少k次

Milk Patterns Description Farmer John has noticed that the quality of milk given by his cows varies from day to day. On further investigation, he discovered that although he can't predict the quality of milk from one day to the next, there are some r