求e的小数位后1000位

tanwan 2009-09-08 03:11:57
谁能给我讲一下这个思路啊,全代码就不用了,网上找过,看不懂。。。我想先知道思路起。。。
...全文
664 33 打赏 收藏 转发到动态 举报
写回复
用AI写文章
33 条回复
切换为时间正序
请发表友善的回复…
发表回复
linren 2009-09-09
  • 打赏
  • 举报
回复
[Quote=引用 27 楼 tanwan 的回复:]
引用 21 楼 xingzhe2001 的回复:
引用 11 楼 tanwan 的回复:
你说单单的1/7之类这样的模拟我可以实现到N位,但是你说用一个变量保存如450!这样怎么保存?


用数组保存,比如用数组 int[1000]保存,为了进位方便,可以用int[1004]. 每个项int[i]表示1000位小数中的一位。



450!你用什么存下来?
[/Quote]
可以用char的数组来保存……
会节省一些空间……

把数用10进制存放……
数组中的每个char表示10进制中的某位上的数字……
比如说建立了一个4位的char数组……
存放数字1999的方式可以为:
char array[4];
array[0]=9;
array[1]=9;
array[2]=9;
array[3]=1;

十进制的加法、乘法、除法的运算方法都很简单……
可以自己写一些函数实现以上的运算……

然后是定点运算的部分……
1+1/1!+1/2!+...+1/450!
=[450!+450!+3*4*...*450+...+450+1]/450!

450!+450!+3*4*...*450+...+449*450+450+1 = a

450! = b
可以同时进行计算(红色字体从右到做的顺序)……

分别计算好后再计算:
a*10^1000/b

打印的时候打印array[999...0]即为小数点后1000位的内容……
tanwan 2009-09-09
  • 打赏
  • 举报
回复
谢谢大家
tanwan 2009-09-09
  • 打赏
  • 举报
回复
[Quote=引用 21 楼 xingzhe2001 的回复:]
引用 11 楼 tanwan 的回复:
你说单单的1/7之类这样的模拟我可以实现到N位,但是你说用一个变量保存如450!这样怎么保存?


用数组保存,比如用数组 int[1000]保存,为了进位方便,可以用int[1004]. 每个项int[i]表示1000位小数中的一位。


[/Quote]
450!你用什么存下来?
linren2 2009-09-09
  • 打赏
  • 举报
回复
[Quote=引用 18 楼 linren 的回复:]
需要满足的条件应该是:(n+1)!>2*10^1000
n=?

[/Quote]
一个计算阶乘位数的办法……

例如1000阶乘位数:
log10(1)+log10(2)+···+long10(1000)取整后加1
或者
log(N!)=lnN!/ln10
=(NlnN-N)/ln10
=2565.7

于是……
N!=10^2565.7
=10^.7*10^2565
=5.01e2565

可以从1000开始递减搜索……
999、998、...

以上方法来自:
http://zhidao.baidu.com/question/4978253.html
linren 2009-09-09
  • 打赏
  • 举报
回复
需要满足的条件应该是:(n+1)!>2*10^1000
n=?

AJrxin 2009-09-09
  • 打赏
  • 举报
回复
学习
linren 2009-09-09
  • 打赏
  • 举报
回复
【20楼连接程序中关于精度的计算】
#include <stdio.h>
#include <math.h>
int maxNForCalcE(int d){
double f=d*log(10);
double r=0;
int i=0;
do{
i++;
r += log(i);
}while (r<f);
return i;
}

int main(){
printf("%d!<10^1000\n",maxNForCalcE(1000));
return 0;
}

【运行结果】
450!<10^1000
Press any key to continue


【说明】
非常厉害!
也就是说只用精确计算:1+1/1!+1/2!+...+1/450!
就能得到小数点后1000位了……
linren 2009-09-09
  • 打赏
  • 举报
回复
[Quote=引用 18 楼 linren 的回复:]
需要满足的条件应该是:(n+1)!>2*10^1000
n=?

[/Quote]
【20楼连接中第9楼程序中关于的精度说明】
# //欲达到n位有效数字,需使得 n!> 10^n
# //返回计算d位有效数字所需的最大的n


对于不等式:
(n+1)!>2*10^1000 ①

两边同时除以n+1
n!>[2/(n+1)]*10^1000 ②

如果满足
n!>10^1000

就自然满足了②……

不过注释中的两个n不是同一个n……
可能修改成为这样会比较好:
# //欲达到d位有效数字,需使得 n!> 10^d
# //返回计算d位有效数字所需的最大的n
linren 2009-09-09
  • 打赏
  • 举报
回复
(上接18楼)

【程序】
#include<stdio.h>

int fun(int a){
int n=0,i,s=1;
for(i=2;i<=a;i++){
s*=i;
while(s>9999999){
s/=10;n++;
}
}
while(s){
n++;s/=10;
}
return n;
}

int main(){
long i;
for(i=580;i<600;i++){
printf("%d!->%ld\n",i,fun(i));
}
return 0;
}

【运行结果】
580!->997
581!->999
582!->1000
583!->998
584!->999
585!->1001
586!->1004
587!->1004
588!->1007
589!->1009
590!->1010
591!->1012
592!->1015
593!->1014
594!->1017
595!->1019
596!->1022
597!->1024
598!->1027
599!->1029
Press any key to continue


【说明】
也就是说只要能精确计算:1+1/1!+1/2!+...+1/585!
就能得到e的小数点后1000位的精确结果……
xingzhe2001 2009-09-09
  • 打赏
  • 举报
回复
[Quote=引用 20 楼 gxqcn 的回复:]
请见 liangbch 发的计算百万位e
[/Quote]
20楼的连接讲的很详细,从推导到实现代码都很清晰。
xingzhe2001 2009-09-09
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 tanwan 的回复:]
你说单单的1/7之类这样的模拟我可以实现到N位,但是你说用一个变量保存如450!这样怎么保存?
[/Quote]

用数组保存,比如用数组 int[1000]保存,为了进位方便,可以用int[1004]. 每个项int[i]表示1000位小数中的一位。

linren 2009-09-09
  • 打赏
  • 举报
回复
[Quote=引用 32 楼 tanwan 的回复:]

那总的看来就是要用大数的方法了咯?
[/Quote]恩
的确是这样……

HugeCalc这个大数库好像不错的样子^_^……
gxqcn 2009-09-09
  • 打赏
  • 举报
回复
请见 liangbch 发的 计算百万位e
tanwan 2009-09-09
  • 打赏
  • 举报
回复
[Quote=引用 29 楼 linren 的回复:]
引用 27 楼 tanwan 的回复:
引用 21 楼 xingzhe2001 的回复:
引用 11 楼 tanwan 的回复:
你说单单的1/7之类这样的模拟我可以实现到N位,但是你说用一个变量保存如450!这样怎么保存?


用数组保存,比如用数组 int[1000]保存,为了进位方便,可以用int[1004]. 每个项int[i]表示1000位小数中的一位。


450!你用什么存下来?

可以用char的数组来保存……
会节省一些空间……

把数用10进制存放……
数组中的每个char表示10进制中的某位上的数字……
比如说建立了一个4位的char数组……
存放数字1999的方式可以为:
char array[4];
array[0]=9;
array[1]=9;
array[2]=9;
array[3]=1;

十进制的加法、乘法、除法的运算方法都很简单……
可以自己写一些函数实现以上的运算……

然后是定点运算的部分……
1+1/1!+1/2!+...+1/450!
=[450!+450!+3*4*...*450+...+450+1]/450!

450!+450!+3*4*...*450+...+449*450+450+1 = a

450! = b
可以同时进行计算(红色字体从右到做的顺序)……

分别计算好后再计算:
a*10^1000/b

打印的时候打印array[999...0]即为小数点后1000位的内容……
[/Quote]
那总的看来就是要用大数的方法了咯?
24K純帥 2009-09-09
  • 打赏
  • 举报
回复
天呐,这得怎么做
linren 2009-09-09
  • 打赏
  • 举报
回复
[Quote=引用 25 楼 linren 的回复:]
【20楼连接程序中关于精度的计算】
C/C++ code#include<stdio.h>
#include<math.h>int maxNForCalcE(int d){double f=d*log(10);double r=0;int i=0;do{
i++;
r+= log(i);
}while (r<f);return i;
}int main(){
printf("%d!<10^1000\n",maxNForCalcE(1000));return0;
}
【运行结果】
Assembly code450!<10^1000
Press any key to continue

【说明】
非常厉害!
也就是说只用精确计算:1+1/1!+1/2!+...+1/450!
就能得到小数点后1000位了……
[/Quote]
突然发现25楼把不等号写错了……
应该是:
printf("%d!>10^1000\n",maxNForCalcE(1000));
linren 2009-09-08
  • 打赏
  • 举报
回复
[Quote=引用 15 楼 peacefulby 的回复:]

是小数点后1000位不是1/1000……
[/Quote]
明白了
误差是需要小于1/(10^1000)……
linren 2009-09-08
  • 打赏
  • 举报
回复
也就是说只要计算517/720……
就能得到误差不超过2/5040=1/2520的e的值……
PeacefulBY 2009-09-08
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 linren 的回复:]
感觉上是需要把浮点运算改为定点的大数运算……
精度部分需要满足不等式:1/(n+1)!+1/(n+2)!+.... <1/1000

1/(n+1)!+1/(n+2)!+1/(n+3)!....
=1/[1*2*...*(n+1)]+1/[1*2*...*(n+1)*(n+2)]+1/[1*2*...*(n+1)*(n+2)*(n+3)]...
=(1/1!)*(1/[2*3*...*(n+1)])+(1/2!)*(1/[3*4*...*(n+1)*(n+2)])+(1/3!)*(1/[4*5*...*(n+1)*(n+2)*(n+3)])...

因为:
(n+1)!=2*3*...*(n+1) <3*4*...*(n+1)*(n+2) <4*5*...*(n+1)*(n+2)*(n+3)

所以:
1/(n+1)!+1/(n+2)!+1/(n+3)!.... <(1/1!+1/2!+...)*(1/(n+1)!) = e*(1/(n+1)!) < 3*(1/(n+1)!)

使:3*(1/(n+1)!) <1/1000
(n+1)!>3000

得n=6
(n+1)!=7!=5040>3000

也就是说只要能精确计算
1/1!+1/2!+1/3!+1/4!+1/5!+1/6!

就可以得到小数点后1000位的精确值了……
[/Quote]
是小数点后1000位不是1/1000……
linren 2009-09-08
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 linren 的回复:]

也就是说只要能精确计算
1/1!+1/2!+1/3!+1/4!+1/5!+1/6!

就可以得到小数点后1000位的精确值了……
[/Quote]
漏掉了前面的1了……

重新写一下:

1/(n+1)!+1/(n+2)!+1/(n+3)!....
=1/[1*2*...*(n+1)]+1/[1*2*...*(n+1)*(n+2)]+1/[1*2*...*(n+1)*(n+2)*(n+3)]...
=(1/1!)*(1/[2*3*...*(n+1)])+(1/2!)*(1/[3*4*...*(n+1)*(n+2)])+(1/3!)*(1/[4*5*...*(n+1)*(n+2)*(n+3)])...

因为:
(n+1)!=2*3*...*(n+1) <3*4*...*(n+1)*(n+2) <4*5*...*(n+1)*(n+2)*(n+3)

所以:
1/(n+1)!+1/(n+2)!+1/(n+3)!.... <(1/1!+1/2!+...)*(1/(n+1)!) = (e-1)*(1/(n+1)!) < 2*(1/(n+1)!)

使:2*(1/(n+1)!) <1/1000
(n+1)!>2000

得n=6
(n+1)!=7!=5040>2000

也就是说只要能精确计算
1+1/1!+1/2!+1/3!+1/4!+1/5!+1/6!

就可以得到小数点后1000位的精确值了……
加载更多回复(13)

33,028

社区成员

发帖
与我相关
我的任务
社区描述
数据结构与算法相关内容讨论专区
社区管理员
  • 数据结构与算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧