| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 6026 人关注过本帖
标题:求教有关C语言,输入一个精度 eps,用莱布尼茨公式,估算 Pi 值
只看楼主 加入收藏
top398
Rank: 8Rank: 8
等 级:蝙蝠侠
威 望:2
帖 子:427
专家分:857
注 册:2014-5-2
收藏
得分:0 
以下是一个经典的大整数 PI 值计算程序。
程序代码:
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>

const int LONG_TIME = 4000;

char *p;
char *t;
int q;

void l_add()
{
    int j;
    for ( j = q; j >= 0; j-- ) {
        if ( t[j] + p[j] > 9 ) {
            p[j]     += t[j] - 10;
            p[j - 1] += 1;
        } else
            p[j] += t[j];
    }
}

void l_sub()
{
    int j;
    for ( j = q; j >= 0; j-- ) {
        if ( p[j] < t[j] ) {
            p[j]     -= t[j] - 10;
            p[j - 1] -= 1;
        } else
            p[j] -= t[j];
    }
}

void l_mul( int multiplier )
{
    int b;
    int i;
    int carry = 0, digit = 0;
    for ( i = q; i >= 0; i-- ) {
        b     = ( t[i] * multiplier + carry );
        digit = b % 10;
        carry = b / 10;
        t[i]  = digit;
    }
}

/* t[] /= l */
void l_div( int divisor )
{
    int i, b;
    int quotient, remainder = 0;
    for ( i = 0; i <= q; i++ ) {
        b         = ( 10 * remainder + t[i] );
        quotient  = b / divisor;
        remainder = b % divisor;
        t[i]      = quotient;
    }
}

void div4()
{
    int i, c, d = 0;
    for ( i = 0; i <= q; i++ ) {
        c    = ( 10 * d + p[i] ) / 4;
        d    = ( 10 * d + p[i] ) % 4;
        p[i] = c;
    }
}

void mul4()
{
    int i, c, d;
    d = c = 0;
    for ( i = q; i >= 0; i-- ) {
        d    = ( p[i] * 4 + c ) % 10;
        c    = ( p[i] * 4 + c ) / 10;
        p[i] = d;
    }
}

int tiszero()
{
    int k;
    for ( k = 0; k <= q; k++ )
        if ( t[k] != 0 )
            return FALSE;
    return TRUE;
}

void l_arctan( int s )
{
    int n;
    t[0] = 1;
    l_div( s );   /* t[] = 1/s */
    l_add();
    n = 1;
    do {
        l_mul( n );
        l_div( s * s );
        l_div( n += 2 );
        if ( ( ( n - 1 ) / 2 ) % 2 == 0 )
            l_add();
        else
            l_sub();
    } while ( !tiszero() );
}

int main( int argc, char *argv[] )
{
    DWORD startime, endtime;
    int i;
    if ( argc == 2 ) {
        q = atoi( argv[1] );
    } else {
        printf( "Usage: pi [precision]" );
        return 1;
    }
    if ( q < 0 ) {
        printf( "Precision was too low, running with precision of 0." );
        q = 0;
    }
    if ( q > LONG_TIME ) {
        printf( "Be prepared to wait a while..." );
    }
    // Compute one more digit than we display to compensate for rounding
    q++;
    p = malloc( q + 1 );
    t = malloc( q + 1 );
    if ( !p || !t ) {
        printf( "Cannot allocate memory\n" );
        return 2;
    }
    memset( p, 0, q + 1 );
    memset( t, 0, q + 1 );
    /* compute pi */
    startime = GetTickCount();
    l_arctan( 2 );
    l_arctan( 3 );
    mul4();
    endtime = GetTickCount();
    // Return to the number of digits we want to display
    q--;
    /* print pi */
    printf( "pi = %d.", p[0] );
    for ( i = 1; i <= q; i++ )
        printf( "%d", p[i] );
    printf( "\n%d ms to compute pi with a precision of %d digits.",
            endtime - startime, q );
    return 0;
}

2014-05-15 18:27
wfjimy
Rank: 1
等 级:新手上路
帖 子:10
专家分:0
注 册:2014-5-15
收藏
得分:0 
回复 9 楼 top398
如果我想求小数点后20位,怎么改程序呢
2014-05-15 18:27
top398
Rank: 8Rank: 8
等 级:蝙蝠侠
威 望:2
帖 子:427
专家分:857
注 册:2014-5-2
收藏
得分:0 
R:\>gcc pi.c

R:\>a 100
pi = 3.1415926535897932384626433832795028841971693993751058209749445923078164062
862089986280348253421170682
0 ms to compute pi with a precision of 100 digits.
R:\>a 1000
pi = 3.1415926535897932384626433832795028841971693993751058209749445923078164062
86208998628034825342117067982148086513282306647093844609550582231725359408128481
11745028410270193852110555964462294895493038196442881097566593344612847564823378
67831652712019091456485669234603486104543266482133936072602491412737245870066063
15588174881520920962829254091715364367892590360011330530548820466521384146951941
51160943305727036575959195309218611738193261179310511854807446237996274956735188
57527248912279381830119491298336733624406566430860213949463952247371907021798609
43702770539217176293176752384674818467669405132000568127145263560827785771342757
78960917363717872146844090122495343014654958537105079227968925892354201995611212
90219608640344181598136297747713099605187072113499999983729780499510597317328160
96318595024459455346908302642522308253344685035261931188171010003137838752886587
53320838142061717766914730359825349042875546873115956286388235378759375195778185
77805321712268066130019278766111959092164201989
109 ms to compute pi with a precision of 1000 digits.
R:\>
2014-05-15 18:28
wfjimy
Rank: 1
等 级:新手上路
帖 子:10
专家分:0
注 册:2014-5-15
收藏
得分:0 
回复 10 楼 top398
能写一下代码吗,初学者理解有点困难,谢谢😊
2014-05-15 19:25
top398
Rank: 8Rank: 8
等 级:蝙蝠侠
威 望:2
帖 子:427
专家分:857
注 册:2014-5-2
收藏
得分:0 
程序在功能上已经全了。你只要把输入输出适配一下即可。
如:程序中用 命令行参数 argv[1] 传递欲求值的小数位数 q,你可想法将 eps 转换为 q(例如数小数点后0的个数,或求得它是10的负多少次方)。
这点工作还希望你自己动手完成,全写出来照抄无助学习和理解。
2014-05-15 23:10
top398
Rank: 8Rank: 8
等 级:蝙蝠侠
威 望:2
帖 子:427
专家分:857
注 册:2014-5-2
收藏
得分:0 
另外程序中用到 Windows API 计算程序运行时间,可以去掉。
2014-05-15 23:15
快速回复:求教有关C语言,输入一个精度 eps,用莱布尼茨公式,估算 Pi 值
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.026803 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved