user-0 提问: 计算指数级数

回复:
user: user-0
content: 多谢各位大神了！其实小弟当时写这个程序有问题只以为是哪的逻辑可能不对 ，但自己检查好几遍感觉没什么问题就想来发个贴问问。没想到还挺复杂，关键是大神们讨论的东西自己都不太懂，说实话我连级数是什么都不清楚。看来想编好程序数学也确实很重要啊！

user: user-1
content: 引用 23 楼 lm_whales 的回复:e这个常数，应该自己求出来，如果直接获得，就有些突然了。 嗯，是应该自己算出来才能达到指定精度

user: user-2
content: 这里主要利用公式 e^x = 1 + x + x^2/2! + x^3/3! + ....................x^n/n! 来计算 e^x

user: user-2
content: 引用 20 楼 dianyancao 的回复:e^(floor(x))能用O(log(x))次迭代求出 e这个常数，应该自己求出来，如果直接获得，就有些突然了。

user: user-2
content: 引用 20 楼 dianyancao 的回复:e^(floor(x))能用O(log(x))次迭代求出这个也可以这么快？？

user: user-2
content: 引用 17 楼 dianyancao 的回复:计算e^x，由于e是常数，不知道一般的做法是不是用足够的二进制位储存e 然后只计算e^r,  (0<=r<1),r=x-floor(x) 那么e^r * e^(floor(x))即是计算结果  按这样计算e^r,有 0<=item(n)<1 1-item(n)>0 所以当fabs(sum*item /(1-item)) >= 1e-6时精度可以满足要求  引用 16 楼 lm_whales 的回复:R(n) =f(x) *item(n)=(sum(n) +R(n) )*item(n) 这个法子不错 e 可以用  e^1 =e^x = 1 + x + x^2/2! + x^3/3! + ....................x^n/n!+......... | x=1 求出来 e^1 =1+1 +1/2!+1/3!+1/4!+1/5!+....1/n! e^r 可以用公式e^x = 1 + x + x^2/2! + x^3/3! + ....................x^n/n!+......... | x=r 求出来

user: user-3
content: 总不至于上GMP库吧。

user: user-1
content: e^(floor(x))能用O(log(x))次迭代求出

user: user-1
content: 引用 18 楼 lm_whales 的回复:[quote=引用 17 楼 dianyancao 的回复:] e^r 可以用公式e^x = 1 + x + x^2/2! + x^3/3! + ....................x^n/n!+......... | x=r 求出来 这里的r就是整数啦，所以直接O(log(r))次迭代就能求得e^r的结果

user: user-1
content: 计算e^x，由于e是常数，不知道一般的做法是不是用足够的二进制位储存e 然后只计算e^r,  (0<=r<1),r=x-floor(x) 那么e^r * e^(floor(x))即是计算结果  按这样计算e^r,有 0<=item(n)<1 1-item(n)>0 所以当fabs(sum*item /(1-item)) >= 1e-6时精度可以满足要求  引用 16 楼 lm_whales 的回复:R(n) =f(x) *item(n)=(sum(n) +R(n) )*item(n) 这个式子应该是|R(n)|<=|(sum(n) +R(n) )*item(n)|，即 R(n)*(1-item(n))<=sum(n)*item(n) 当1-item(n)<0时，得到 R(n)>=sum*item /(1-item) 用来估计误差上界似乎不合适，不过测试了多个例子精度都满足要求

user: user-2
content: f(x) =sum(n) +R(n) R(n) =f(x) *item(n)=(sum(n) +R(n) )*item(n) R(n) = sum(n) *item(n) /(1 -item(n) ) 这样看来，应该改成 sum(n) *item(n) /(1 -item(n) ) 即判断 sum *item /(1 -item )   #include <iostream>  double e( int x );  int main( void ) { 	int x; 	printf( "please input x :" ); 	scanf( "%d" , &x );  	printf( "\nThe result of e^%d is %-10.6f\n" , x , e( x ) );  	return 0; }  double e( double x ) { 	double item = 1.0 ; 	double sum = 0; 	int i = 1;         int plus = x > 0;//当x 为负数的时候，e^-x =1/e^x ,负数计算的精度不够，所以改为求正数的幂。 	do 	{ 		sum += item; 		item = item * x / i; 		i++; 	}while( fabs( sum *item /(1 -item )  ) >= 1e-6 );	  	return sign? sum: 1/ sum ; } 这样，在不计算，浮点数表示，精度损失的情况下，是不是算可以了。

user: user-2
content: R(n)| <=|f(sum,item,n,x)|

user: user-2
content: 引用 13 楼 dianyancao 的回复:好像不行，这样要求|sum|>=e^|x|才行，但是|sum|<e^|x|  ++ 试了一下，起码对于负数结果是不正确的 不知道有什么办法，让某个已经计算出来的 数据，替换 e^r   或者从已经计算出来的结果中,得到一个式子， f(sum,item,i,x) 使得|R(n)| <=|f(sum,item,i,x)|

user: user-0
content: 引用 3 楼 user-5 的回复:问题就在于当x^n/n!小于10^-6时，后面的其它数的和，还有可能进位。  没懂您的意思 当x^n/n!小于10^-6时不就只有一项吗?

user: user-1
content: 引用 10 楼 lm_whales 的回复:[quote=引用 9 楼 dianyancao 的回复:] 这里是错了，该幂级数的拉格朗日型余项是|R(n)|=|(e^r*x^(n+1))/(n+1)!|<|e^|x|*x^(n+1))/(n+1)!| 这个|R(n)|就是用前n+1项近似产生的误差值上界 ++ 既然如此，这里，可以近似的让 f(x) = e^x  =  sum(n) 这样,R(n) =f(x) *x^(n+1))/(n+1)! ~=sum(n) *x^(n+1)/(n+1)!  sum += item;         item = item * x / i; 此时，item = x^(i+1)/(i+1)! R(i) = sum(i) *x^(i+1)/(i+1)!  = sum *item; 只要 fabs(sum *item) < 10^-6 即可 编程,果然还是要数学好 这应该差不多了 如果还不够严格，各位大牛继续讨论  [/quote] 好像不行，这样要求|sum|>=e^|x|才行，但是|sum|<e^|x|

user: user-2
content: 更高精度，要用到高精度浮点数或者定点数表示， 64Bits浮点数，计算exp(50) ，甚至exp(30) 已经很不精确了。

user: user-2
content: 另外，这个改进，对于精度为 1e-3 效果明显，对于 1e-6，及更高精度， 效果不大。   引用 1 楼 FancyMouse 的回复:e^5不是应该148.41么 ++ 确实是148.41 Windows 计算器的结果大约是，148.41315910257660342111558004055 楼主149.372018 和138.307168的两个结果都是错误的，精度误差也太大了。

user: user-2
content: 引用 9 楼 dianyancao 的回复:这里是错了，该幂级数的拉格朗日型余项是|R(n)|=|(e^r*x^(n+1))/(n+1)!|<|e^|x|*x^(n+1))/(n+1)!| 这个|R(n)|就是用前n+1项近似产生的误差值上界 ++ 既然如此，这里，可以近似的让 f(x) = e^x  =  sum(n) 这样,R(n) =f(x) *x^(n+1))/(n+1)! ~=sum(n) *x^(n+1)/(n+1)!  sum += item;         item = item * x / i; 此时，item = x^(i+1)/(i+1)! R(i) = sum(i) *x^(i+1)/(i+1)!  = sum *item; 只要 fabs(sum *item) < 10^-6 即可 编程,果然还是要数学好 这应该差不多了 如果还不够严格，各位大牛继续讨论

user: user-4
content: 数学分析中要作“误差分析“，算得再多也是作无用功！

user: user-5
content: 问题就在于当x^n/n!小于10^-6时，后面的其它数的和，还有可能进位。