我想把e的值近似到任何想要的精度。 最好的方法是什么? 我能够得到的最多的值是e=2.7182818284590455。如果有任何修改下面代码的例子,我将感激不尽。
public static long fact(int x){
long prod = 1;
for(int i = 1; i <= x; i++)
prod = prod * i;
return prod;
}//fact
public static void main(String[] args) {
double e = 1;
for(int i = 1; i < 50; i++)
e = e + 1/(double)(fact(i));
System.out.print("e = " + e);
}//main
使用一个 大十进制 而不是双倍。
BigDecimal e = BigDecimal.ONE;
BigDecimal fact = BigDecimal.ONE;
for(int i=1;i<100;i++) {
fact = fact.multiply(new BigDecimal(i));
e = e.add(BigDecimal.ONE.divide(fact, new MathContext(10000, RoundingMode.HALF_UP)));
}
你的主要问题是 double
的精度非常有限。如果你想要任意的精度,你将不得不使用 BigDecimal
. 下一个问题你会遇到的是有限的范围内的 long
在这里你可以使用 BigInteger
.
你有没有看一下任意精度的算术?java.util.BigDecimal
?
import java.math.BigDecimal;
import java.math.MathContext;
public class BigExp {
public static void main(String[] args) {
BigDecimal FIFTY =new BigDecimal("50");
BigDecimal e = BigDecimal.ZERO;
BigDecimal f = BigDecimal.ONE;
MathContext context = new MathContext(1000);
for (BigDecimal i=BigDecimal.ONE; i.compareTo(FIFTY)<0; i=i.add(BigDecimal.ONE)) {
f = f.multiply(i, context);
e = e.add(i.divide(f,context),context);
System.out.println("e = " + e);
}
}
}
如果你从49数到1,而不是像现在这样从1数到49,你会得到更好的结果。
用Zed和mobrule的代码的变化。效果很好,谢谢 更多的性能建议任何人?
public static BigDecimal factorial(int x){
BigDecimal prod = new BigDecimal("1");
for(int i = x; i > 1; i--)
prod = prod.multiply(new BigDecimal(i));
return prod;
}//fact
public static void main(String[] args) {
MathContext mc = new MathContext(1000);
BigDecimal e = new BigDecimal("1", mc);
for(int i = 1; i < 1000; i++)
e = e.add(BigDecimal.ONE.divide(factorial(i), mc));
System.out.print("e = " + e);
}//main
更多的性能建议有人知道吗?
是的,你对因子的计算效率太低了。 最好是把它移到你求和项的循环里面。 你的做法把一个O(N)问题变成了一个O(N^2)问题。
如果这是一个真正的计算,需要阶乘,我建议用表格查找或不完全伽马函数作为正确的方法。
从性能的角度来看,你唯一能做得更差的就是递归的阶乘计算。 那么你就会有一个额外的问题,那就是巨大的堆栈。
要理解为什么你不能用以下方法获得 "任何想要的精度"。double
,阅读这篇经典论文。
请注意,这是一篇技术性很强的论文。更多关于浮点数字工作原理的基本细节,请看维基百科的文章。双精度浮点格式
使用BigDecimal类可以得到e的最佳近似值。
以下是计算给定的BigDecimal值的代码。
import java.math.BigDecimal;
import java.math.MathContext;
public class ApproximateE {
public static void main(String[] args) {
System.out.println("e~ "+e(new BigDecimal(50)));//the value to approximate
}
static BigDecimal e(BigDecimal n) {
BigDecimal num = new BigDecimal(n + "");
BigDecimal e = BigDecimal.ZERO;
BigDecimal f = BigDecimal.ONE;
MathContext context = new MathContext(25);//digits of precision
/************************************************************************
The formula for approximating e ~
e = 1+(1/1!+1/2!+1/3!...1/i!)
************************************************************************/
for (BigDecimal i = BigDecimal.ONE; i.compareTo(num) < 0; i = i.add(BigDecimal.ONE)) {
f = f.multiply(i, context);
e = e.add(i.divide(f, context), context);
}
return e;
}
}
返回 。
e~ 2.718281828459045235360289
f的值是
1
2
6
24
120
720
5040
40320
362880
3628800
39916800
479001600
6227020800
87178291200
1307674368000
20922789888000
355687428096000
6402373705728000
121645100408832000
2432902008176640000
51090942171709440000
1124000727777607680000
25852016738884976640000
620448401733239439360000
1.551121004333098598400000E+25
4.032914611266056355840000E+26
1.088886945041835216076800E+28
3.048883446117138605015040E+29
8.841761993739701954543616E+30
2.652528598121910586363085E+32
8.222838654177922817725564E+33
2.631308369336935301672180E+35
8.683317618811886495518194E+36
2.952327990396041408476186E+38
1.033314796638614492966665E+40
3.719933267899012174679994E+41
1.376375309122634504631598E+43
5.230226174666011117600072E+44
2.039788208119744335864028E+46
8.159152832478977343456112E+47
3.345252661316380710817006E+49
1.405006117752879898543143E+51
6.041526306337383563735515E+52
2.658271574788448768043627E+54
1.196222208654801945619632E+56
5.502622159812088949850307E+57
2.586232415111681806429644E+59
1.241391559253607267086229E+61
6.082818640342675608722522E+62
e的值是
1
2
2.5
2.666666666666666666666667
2.708333333333333333333334
2.716666666666666666666667
2.718055555555555555555556
2.718253968253968253968254
2.718278769841269841269841
2.718281525573192239858906
2.718281801146384479717813
2.718281826198492865159532
2.718281828286168563946342
2.718281828446759002314558
2.718281828458229747912288
2.718281828458994464285470
2.718281828459042259058794
2.718281828459045070516048
2.718281828459045226708118
2.718281828459045234928753
2.718281828459045235339785
2.718281828459045235359358
2.718281828459045235360248
2.718281828459045235360287
2.718281828459045235360289
2.718281828459045235360289
...