电光石火-穿越时空电光石火-穿越时空


圆周率代码

c语言

#include <stdio.h>
#define L 100000 //求100000位PI值
#define N L/4+1

// L 为位数,N是array长度
/*圆周率后的小数位数是无止境的,如何使用电脑来计算这无止境的小数是一些数学家与程式设计师所感兴趣的,在这边介绍一个公式配合 大数运算,可以计算指定位数的圆周率。
J.Marchin的圆周率公式:
PI = [16/5 - 16 / (3*53) + 16 / (5*55) - 16 / (7*57) + ......] -  [4/239 - 4/(3*2393) + 4/(5*2395) - 4/(7*2397) + ......]
*/
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] < 100000 )
            carry = 0;
        else   // 进位
        {
            c[i] = c[i] - 100000;
            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] + 100000;
            borrow = 1;
        }
    }
}

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

go语言

package main

import (
    "fmt"
)

type myInt int32

const (
    SIZE    = 120      //数组长度  数据长度小于:120*9
    TIMES   = 10000000 //迭代次数
    PRESIZE = 1000     //数字的有效位数
)

/*
*代码作者:天之
*博客:http://blog.csdn.net/WAPWO?viewmode=contents
 */
func main() {
    res, bRes := make([]byte, PRESIZE), make([]byte, PRESIZE)
    rab(res, bRes)
    int4Res(res)
    fmt.Println("\n", res)
}

/*  圆周率 4*[1-1/3+1/5-1/7+...]  */
func rab(res, bRes []byte) {
    intDiv(2, 3, res)
    var x myInt = 5
    for i := 2; i < TIMES; i++ {
        intDiv(1, x, bRes)
        if i&1 == 0 {
            intSum(res, bRes)
        } else {
            intDif(res, bRes)
        }
        x += 2
    }
}

/*四倍的sum*/
func int4Res(res []byte) {
    tmp := make([]byte, PRESIZE)
    cpyByteArr(tmp, res)
    intSum(res, tmp)
    intSum(res, tmp)
    intSum(res, tmp)
}

/*求和值  res=res-bRes  (因为已知是不会溢出的) */
func intSum(res, bRes []byte) {
    var count byte
    for i := PRESIZE - 1; i >= 0; i-- {
        count = res[i] + bRes[i]
        if count >= 10 {
            res[i-1] += 1
            res[i] = count - 10
        } else {
            res[i] = count
        }
    }
}

/*求差值  res=res-bRes  (因为已知是不会溢出的) */
func intDif(res, bRes []byte) {
    var j int
    for i := PRESIZE - 1; i >= 0; i-- {
        if res[i] < bRes[i] {
            for j = i - 1; res[j] == 0; j-- {
                res[j] = 9
            }
            res[j] -= 1
            res[i] = res[i] - bRes[i] + 10
        } else {
            res[i] = res[i] - bRes[i]
        }
    }
}

/*求除数  res=a/b  */
func intDiv(a, b myInt, res []byte) {
    var count byte
    for i := 0; i < PRESIZE; i++ {
        count = (byte)(a / b)
        if count == 0 {
            a *= 10
            res[i] = 0
        } else {
            a %= b
            a *= 10
            res[i] = count
        }
    }
}

/*复制整型数组*/
func cpyByteArr(d, s []byte) {
    for i := 0; i < PRESIZE; i++ {
        d[i] = s[i]
    }
}
本博客所有文章如无特别注明均为原创。作者:似水的流年
版权所有:《电光石火-穿越时空》 => 圆周率代码
本文地址:http://ilkhome.cn/index.php/archives/836/
欢迎转载!复制或转载请以超链接形式注明,文章为 似水的流年 原创,并注明原文地址 圆周率代码,谢谢。

评论