优化c代码计算pi

优化c代码计算pi,c,pi,C,Pi,我已经编写了C代码来计算 无注释的代码如下所示: #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/num

我已经编写了C代码来计算

无注释的代码如下所示:

#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;
}
#包括
#定义数字100000
整数数组除以整数(整数*数组,整数,整数大小)
{
int i,tmp;
整数模=0;
对于(i=0;i=0;最后--)
{
如果(数组[上次]!=0)
{
打破
}
}
对于(i=0;i9)
{
总和[i]=总和[i]%10;
和[i-1]++;
}
}
}
空减法数组(int*minuend,int*subtractor,int*answer,int size)
{
int i;
对于(i=size-1;i>=0;i--)
{
如果(分钟[i]>=减法器[i]|i==0)
{
答案[i]=分钟[i]-减法器[i];
}
其他的
{
如果(分钟[i-1]==0)
{
分钟[i-2]-;
分钟[i-1]=10;
}
分钟[i-1]-;
答案[i]=10+分钟[i]-减法器[i];
}
}
}
int main()
{
int i;
int标志=1;
int d5[NUMBER]={0};
int t5[NUMBER]={0};
int d239[NUMBER]={0};
int t239[数字]={0};
int-pi[NUMBER]={0};
d5[0]=16;
d239[0]=4;
数组除以数(d5,5,数字);
数组除数(D239239,数字);
//每次迭代将增加三个有效数字
对于(i=1;i 0)
{
加_数组(pi,t5,pi,NUMBER);
减_数组(pi,t239,pi,NUMBER);
}
其他的
{
减_数组(pi,t5,pi,NUMBER);
加_数组(pi,t239,pi,NUMBER);
}
flag=-1*标志;
数组除数(d5,5*5,数字);
数组除数(D239239*239,数字);
}
打印数组(pi,编号);
返回0;
}
它可以工作,但需要的时间太长:

$time./16_pi.exe>pi3.log
/16_pi.exe>pi3.log 617.76s用户0.15s系统98%cpu 10:27.94总计

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

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

你在做算术。Bignum算法既难又聪明。您应该使用一个bignum库,比如(它可能还得益于特殊的进位传播机器指令;主要的好处是聪明的bignum算术算法),它可能比您天真的bignum例程运行得更快

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

FWIW,另见。GMP有一个结论:计算100000个数字只需一小段时间。

优化代码会以某种方式改变算法(即使公式相同)

你在做算术。Bignum算法既难又聪明。您应该使用一个bignum库,比如(它可能还得益于特殊的进位传播机器指令;主要的好处是聪明的bignum算术算法),它可能比您天真的bignum例程运行得更快

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


FWIW,另见。GMP有一个问题:计算100000位数字只需一小段时间。

您是如何编译代码的?在哪个编译器、编译选项、操作系统上?有一些惊人的系列非常快地收敛到pi。。。维基百科有一个bunchI,用来编译我的代码。我的操作系统是Ubuntu 14.04.1 LTS。你是如何编译代码的?在哪个编译器、编译选项、操作系统上?有一些惊人的系列非常快地收敛到pi。。。维基百科有一个bunchI,用来编译我的代码。我的操作系统是Ubuntu 14.04.1 LTS。