首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >优化c代码计算pi

优化c代码计算pi
EN

Stack Overflow用户
提问于 2015-01-09 06:14:43
回答 1查看 200关注 0票数 0

我编写了C代码在pi.c上计算pi.c

没有注释的代码列出如下:

代码语言:javascript
复制
#include <stdio.h>
#define NUMBER 100000
int array_divide_number(int *array, int number, int size)
{
    int i,tmp;
    int modulo=0;
    for(i=0;i<size;i++)
    {
    tmp = array[i]+modulo*10;
    array[i] = tmp/number;
    modulo = tmp%number;
    }
    return 0;
}
void print_array(int *array, int size)
{
    int i,last;
    for(last=size-1;last>=0;last--)
    {
    if(array[last] != 0)
    {
        break;
    }
    }
    for(i=0;i<=last;i++)
    {
    printf("%d",array[i]);
    }
    printf("\n");
}
void copy_array(int *source, int *target, int size)
{
    int i;
    for(i=0;i<size;i++)
    {
    target[i] = source[i];
    }
}
void plus_array(int *augend, int *addend, int *sum, int size)
{
    int i;
    for(i=size-1;i>=0;i--)
    {
    sum[i] = augend[i] + addend[i];
    if(sum[i]>9)
    {
        sum[i] = sum[i] % 10;
        sum[i-1]++;
    }
    }
}
void minus_array(int *minuend, int *subtracter, int *answer, int size)
{
    int i;
    for(i=size-1;i>=0;i--)
    {
    if(minuend[i] >= subtracter[i] || i == 0)
    {
        answer[i] = minuend[i] - subtracter[i];
    }
    else
    {
        if(minuend[i-1] == 0)
        {
            minuend[i-2]--;
            minuend[i-1] = 10;
        }
        minuend[i-1]--;
        answer[i] = 10 + minuend[i] - subtracter[i];
    }
    }
}
int main()
{
    int i;
    int flag=1;
    int d5[NUMBER]={0};
    int t5[NUMBER]={0};
    int d239[NUMBER]={0};
    int t239[NUMBER]={0};
    int pi[NUMBER]={0};
    d5[0]=16;
    d239[0]=4;
    array_divide_number(d5,5,NUMBER);
    array_divide_number(d239,239,NUMBER);
    //every iteration will increase three valid digitals
    for(i=1;i<NUMBER*3/2;i+=2)
    {
    copy_array(d5, t5, NUMBER);
    copy_array(d239, t239, NUMBER);
    array_divide_number(t5,i,NUMBER);
    array_divide_number(t239,i,NUMBER);
    if(flag > 0)
    {
        plus_array(pi,t5,pi,NUMBER);
        minus_array(pi,t239,pi,NUMBER);
    }
    else
    {
        minus_array(pi,t5,pi,NUMBER);
        plus_array(pi,t239,pi,NUMBER);
    }
    flag = -1*flag;
    array_divide_number(d5,5*5,NUMBER);
    array_divide_number(d239,239*239,NUMBER);
    }
    print_array(pi, NUMBER);
    return 0;
}

它很有效,但花费的时间太长了:

$time ./16_pi.exe >pi3.log ./16_pi.exe > pi3.log 617.76s user 0.15s system 98% cpu 10:27.94 total

你可以看到,为了计算pi的100000位数,需要超过10分钟。有没有一种在不改变计算pi=(16/5-4/239)-1/3*(16/5^3-4/239^3)+1/5*(16/5^5-4/239^5)+...)算法的情况下优化代码的方法(这里使用的算法是pi )

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-01-09 06:33:59

优化代码在某种程度上改变了算法(即使公式相同)。

你在做一些大体算法。Bignum算法又难又聪明。您应该使用象GMPlib这样的bignum库(它也可能从特殊的进位传播机器指令中获益;主要的好处是聪明的bignum算术算法),它可能比您天真的bignum例程运行得更快。

当然,不要忘记在基准测试时要求编译器进行优化(例如gcc -O3 -Wall -mtune=native)

请参阅关于Pi的页面。GMP有一个页中有关于Pi的代码:计算100,000位数只需一小部分秒。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27854846

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档