首页
社区
课程
招聘
[求助]谁能给个算数值e的高精度算法
发表于: 2010-7-17 23:27 4793

[求助]谁能给个算数值e的高精度算法

2010-7-17 23:27
4793
请问哪位大侠能够给出一个求e的c语言的代码,精度要求至少100位。

[课程]FART 脱壳王!加量不加价!FART作者讲授!

收藏
免费 0
支持
分享
最新回复 (14)
雪    币: 37
活跃值: (25)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
2
使用搜索引擎是独立解决问题的第一步 试试看
2010-7-18 00:59
0
雪    币: 246
活跃值: (25)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
3
试试这个:
// c/c++ 计算 e
// 输入:
// int length : 希望计算的长度,例如10000为希望计算到小数点后一万位
// char * result : 结果存储,需要预先分配空间。在本函数中数字0-9存储为 0x00 - 0x09,如果希望存储可直接打印的字符,应加‘0’
// 在p4 2Ghz, 2G mem的机器上测试,计算小数点后10000位在1秒以内
//

void calculateE(int length, char * result)
{
// e = 1 + 1 + 1/2! + 1/ 3! + 1/4! + ..... + 1/n!

        assert(result);
        char * tmp;
        char * lastTmp;
        char * tempResult[2];
        tempResult[0] = new char[length];
        tempResult[1] = new char[length];
        tmp = tempResult[0];
        lastTmp = tempResult[1];
        int tmpIndex = 0;
        memset(lastTmp,0,length);
        lastTmp[0] = 1;           

    for (int cal = 2;cal <= length; ++cal)
    {

                memset(tmp,0,length);
                int firstNoZero = 0;
               
                static int div = 1;
                for (;div <= cal; ++div)
                {
                        int quo = 0;
                        int rem = 0;
                        for (int j = 0; j< length; ++j)
                        {
                                quo = rem * 10 + lastTmp[j];
                                rem = quo % div;
                                quo = quo / div;
                                tmp[j] = quo;
                                if (firstNoZero == 0 && div == cal && tmp[j] != 0)
                                {
                                        firstNoZero = j;
                                }
                        }
                }
                div = cal;

                 int flag = 0;
                 if (firstNoZero == 0) // All zero
                 {
                         break; // no need to calculate anymore
                 }

                 for (int i = length - 1; i >= firstNoZero - 1; --i)
                 {
                        int tmp_sum = tmp[i] + result[i] + flag;
                        flag = (tmp_sum >= 10 ? 1 : 0);
                        result[i] = (flag ? tmp_sum - 10 : tmp_sum);
                 }     

                 lastTmp = tmp;
                 tmpIndex = (tmpIndex ? 0 : 1);
                 tmp = tempResult[tmpIndex];

        }

        delete[] tempResult[0];
        delete[] tempResult[1];
        result[0] += 2;

}

注:非本人原创,原作者不详。
2010-7-18 11:20
0
雪    币: 109
活跃值: (21)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
编译通不过呀
2010-7-19 00:27
0
雪    币: 246
活跃值: (25)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
5
谈谈你的机器配置、操作系统、编译环境、错误现象。让大家看看是怎么回事。
2010-7-19 10:08
0
雪    币: 101
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
什么操作系统,环境,结果也出现差异的。
2010-7-19 12:37
0
雪    币: 724
活跃值: (81)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
7
3楼算法本身有BUG, 2.7182818284590计算结果却是2.7182818284580,进位逻辑有问题。
2010-7-19 17:19
0
雪    币: 246
活跃值: (25)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
8
看来编译过了,能否说一下编译环境什么的?希望能给出一个修正办的。
再贴一个大家试试:

//理论可计算两亿位,不过最好不要输入1000以上的位数,你会无法忍守。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void add(char *data,char *dataed,int bit);
void reciprocal(char *data,int bit,int num);

int main(void)
{
    int bit;
    char *data,*dataed;
    int *rank;
    printf("Input the bit: ");
    scanf("%d",&bit);
    rank=(int*)malloc(sizeof(int)*bit);
    data=(char*)malloc(sizeof(char)*bit);
    dataed=(char*)malloc(sizeof(char)*bit);
    memset((void*)dataed,0,bit);
    printf("Please wait...");
    for (int i=0;i<bit;i++)
    {

            reciprocal(data,bit,i+1);
            add(data,dataed,bit);

    }
    dataed[0]=dataed[0]+1;
    printf("\nThe E is: ");
    for (int i=0;i<bit;i++)
    {
        
        if (i==1)
           printf(".");
        printf("%d",dataed[i]);
        if (i+1%2000==0)
           system("pause");
    }
    free(rank);
    free(data);
    free(dataed);
    system("pause");
    return 0;
}

void reciprocal(char *data,int bit,int num)
{
     int quotient,remainder;
     memset(data,0,bit);
     *data=1;
     for (int i=1;i<=num;i++)
     {
             remainder=0;
             for (int k=0;k<bit;k++)
             {
                 quotient=remainder*10+data[k];
                 remainder=quotient%i;
                 quotient=quotient/i;
                 data[k]=quotient;
             }
     }
}

void add(char* data,char* dataed,int bit)
{
     int flag=0,b_flag;
     for (int i=bit-1;i>=0;i--)
     {
          if (data[i]+dataed[i]+flag>=10)
             b_flag=1;
          else
             b_flag=0;
          dataed[i]=(dataed[i]+data[i]+flag)%10;
          flag=b_flag;     
     }     
}
2010-7-19 17:36
0
雪    币: 724
活跃值: (81)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
9
首先声明,我不是专业人员,只是闲来无事,试了试,3楼的代码我做了一点修改,应该在各平台都可以编译通过:
void calculateE(int length, char * result)
{
        memset(result,0,length);/*原代码未清0,估计要求外部清0*/
        char * tmp;
        char * lastTmp;
        char * tempResult[2];
        tempResult[0] = new char[length];
        tempResult[1] = new char[length];
        tmp = tempResult[0];
        lastTmp = tempResult[1];
        int tmpIndex = 0;
        memset(lastTmp,0,length);
        lastTmp[0] = 1;     
       
        int div = 1;

        for (int cal = 2;cal <= length; ++cal)
        {
                memset(tmp,0,length);
                int firstNoZero = 0;

                //static int div = 1; 放在循环外部声明
                for (;div <= cal; ++div)
                {
                        int quo = 0;
                        int rem = 0;
                        for (int j = 0; j< length; ++j)
                        {
                                quo = rem * 10 + lastTmp[j];
                                rem = quo % div;
                                quo = quo / div;
                                tmp[j] = quo;
                                if (firstNoZero == 0 && div == cal && tmp[j] != 0)
                                        firstNoZero = j;
                        }
                }
                div = cal;

                int flag = 0;
                if (firstNoZero == 0) // All zero
                        break; // no need to calculate anymore

                //for (int i = length - 1; i >= firstNoZero - 1; --i) 进位错,修改如下:
                for (int i = length - 1; i >= firstNoZero - 2; --i)
                {
                        int tmp_sum = tmp[i] + result[i] + flag;
                        flag = (tmp_sum >= 10 ? 1 : 0);
                        result[i] = (flag ? tmp_sum - 10 : tmp_sum);
                }     

                lastTmp = tmp;
                tmpIndex = (tmpIndex ? 0 : 1);
                tmp = tempResult[tmpIndex];

        }

        delete[] tempResult[0];
        delete[] tempResult[1];
        result[0] += 2;
}
2010-7-19 19:46
0
雪    币: 724
活跃值: (81)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
10
上面代码只能按C++代码编译,因为使用了new/delete,输出10000位,我机器需要2.6秒。我的环境,VC6。不过该算法因为使用累加,因此精度打折扣,10000位时,最后4位不精确。8楼代码我没测,似和3楼算法差不多。
2010-7-19 19:49
0
雪    币: 246
活跃值: (25)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
11
水平不错嘛,谢了!
2010-7-19 20:14
0
雪    币: 459
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
先设计一个100位以上的浮点数类吧。我觉得这个问题的核心在怎么提高算法效率上。
2010-7-21 10:25
0
雪    币: 30
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
来看看,学习一下,你要怎么长干啥用的啊
2010-7-21 10:55
0
雪    币: 202
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
用就双精度就行了啊,要那么多搞理论啊
2010-7-21 11:06
0
雪    币: 25
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
e = 2 + 1/2 + 1/3 + ... 1/n
这个n算到70就够100位了,貌似double精度不够,主要是尾数不精确,计算机内的浮点数是用类似科学计数法的方法存的,所以虽然能存300多位的小数,但精度达不到要求,于是只能用大数除法模拟手算,这个很麻烦,平时涉及大数的问题我都用模板的,这个模板12K以上,发不上来。。
2010-7-24 13:09
0
游客
登录 | 注册 方可回帖
返回
//