e自然对数小数点后50000位???

时间:2021-09-07 14:53:22
请问如何才能计算出e自然对数小数点后50000位啊?哪位能帮忙给个算法啊?本人对此不甚精通。
万分感谢啊!高分送上!

17 个解决方案

#1


用微积分的知识来算吧,好象有个什么拉格朗日展式,逐个展开,要多少位都可以的。

#2


哦,说错了,应该是泰勒展式。呵呵。
exp(x) = 1 + (x^1)/1! + (x^2)/2! + ... + (x^n)/n! + o(n) 
想办法编写一个循环,并且保证运算的精度,就可以了。

我们一般所使用的数据,精度是不可能保持在小数点后50000位的,所以,显示结果,可以用字符串的形式来返回。

#3


泰勒展式这东西是在百度搜的吧?我也看了。没看懂。呵呵。

#4



这东西能不能通过欧拉公式eiθ=cosθ+isinθ
算出来呢?

#5


就用泰勒展式就可以了
主要是你计算时控制精度的问题,最好用数组存放吧。

#6


谁能帮忙写下这个函数啊?应该不难吧?其实就写出来如何得到那个数就行。取小数点后50000的值那个应该不难实现

#7


引用 4 楼 shengli_liao 的回复:
这东西能不能通过欧拉公式eiθ=cosθ+isinθ 
算出来呢?

应该也可以,但是好像需要变换

#8


呵呵,程序会写,但是我并非数学专业,这个算法就难啦!

#9


数值分析学过 baidu下吧 呵呵

#10


高人在哪啊!

#11


引用 10 楼 wudiv998 的回复:
高人在哪啊!

这不是有人回答了吗?更多的你可以去查书呀,随便一本高等数学书上都有的。
引用 2 楼 preferme 的回复:
哦,说错了,应该是泰勒展式。呵呵。 
exp(x) = 1 + (x^1)/1! + (x^2)/2! + ... + (x^n)/n! + o(n) 
想办法编写一个循环,并且保证运算的精度,就可以了。 

我们一般所使用的数据,精度是不可能保持在小数点后50000位的,所以,显示结果,可以用字符串的形式来返回。 

#12


package sbTL;


class E {

public int setE(int i){
int sum = 1;
for(int j=i; j>0; j--){
sum = sum*j;
}
return sum;
}
public void getE(int i){
double sum=1;
for(int j=i; j>0; j--){
sum = sum + 1.0/setE(j);
}
System.out.println(sum);
}
}

public class SBTL{

public static void main(String[] args){
E e = new E();
e.getE(50000);

}
}
-------------------------------------------
Infinity

#13


import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.math.BigDecimal;

public class Test01 {

public static void main(String[] args) {

try {

int precision, i;
BufferedReader str = new BufferedReader(new InputStreamReader(
System.in));
System.out.println("输入整数:");
precision = Integer.parseInt(str.readLine());
str.close();

System.out.println("the e is :" + getE(precision+1).setScale(precision, BigDecimal.ROUND_FLOOR).toPlainString());
} catch (Exception e) {
e.printStackTrace();
}
}
/**
 * exp(1) = 1 + 1/1! + 1/2! + ... + 1/n!
 * @param precision
 * @return
 */
public static BigDecimal getE(int precision) {
BigDecimal one = BigDecimal.ONE;
BigDecimal value = BigDecimal.ONE;
BigDecimal n = BigDecimal.ONE;
BigDecimal factorial = BigDecimal.ONE;
BigDecimal lastValue = BigDecimal.ZERO;

while (true){
value = value.add(one.divide(factorial, precision, BigDecimal.ROUND_HALF_UP));
if (value.compareTo(lastValue) == 0) {
break;
} else if (value.compareTo(lastValue) < 0) {
System.out.println("???");
break;
}
n = n.add(one);
factorial = factorial.multiply(n);
lastValue = value;
}

return value;
}


}

#14


以上代码出来的结果有可能不正确
因为在对N的阶乘的倒数连续求和的过程中,所用的加数可能并不是精确的,
有可能累加的过程中出现误差。
快速的解决办法是:
在调用getE方法的时候,传一个更大的值进去;比如说,想用5000的小数,那么,传6000甚至更大,
这样应该可以消掉误差了;但代价是速度肯定会慢些。

至于具体用多少就能消误差,我不推不出来;如果有时间的话,这个5000的例子,可以多试几次测试出来。
我就不想花这个时间了,嘿嘿~

#15


补充说明,我所说的“具体用多少就能消误差”这个问题,一些数学高手应该可以算出来吧:
思路是,比如要N位小数,算出需要累加X次n阶乘的倒数,那么,相应的,用来消误差的位数应该是X的位数+1。
就是说,假如要5000位小数,如果要累加2000次的话,那么取2005位精度来运算足够了

#16


唉,本来想抛砖引玉一下的,怎么就没有人做出来呢。
LZ我给你写的那个表达式,你竟然看不懂么?
我写了一个,e的1次方的算法,给楼主提示一下,
如果要e的x次方的,可能要LZ自己编写了。
/**
 * 
 */
package houlei.test;

import java.math.BigDecimal;

/**
 * 
 *
 * 该类创建于 2008-9-22 下午01:31:44
 * @version 1.0.0
 * @author 侯磊
 */
public class H {

public static void main(String[] args) {
System.out.println(exp(20).toString());
}


/**
 * 该方法返回自然对数e的精确值。参数即为精确度(小数点后几位),
 * 速度比较慢。
 * @param scale 精确度
 * @return 返回自然对数e的精确值
 */
public static BigDecimal exp(int scale){
final BigDecimal a = new BigDecimal(1);
BigDecimal t = new BigDecimal(1);
BigDecimal sum = new BigDecimal(1);

for(int i=1;t.toString().length()<scale;i++){
 t = factorial(i);
 BigDecimal sub = a.divide(t,scale, BigDecimal.ROUND_HALF_UP);
sum=sum.add(sub);
}
return sum;
}

private static BigDecimal factorial(int n){
if(n<1)throw new IllegalArgumentException("参数必须为正整数");
BigDecimal tmp = new BigDecimal(1);
for(int i=2;i<=n;i++){
tmp=tmp.multiply(new BigDecimal(i));
}
return tmp;
}


}

#17



       /**
 * scale为自然对数e的精确度
 * @param args
 */
public static void main(String[] args) {
BigDecimal number = new BigDecimal(1);
BigDecimal value = new BigDecimal(1);
BigDecimal result = new BigDecimal(1);
int scale = 25000;
while(number.intValue() <= scale){
value = value.divide(number,scale,BigDecimal.ROUND_HALF_UP);
result = result.add(value);
number = number.add(BigDecimal.valueOf(1));
}
System.out.println(result);
}

#1


用微积分的知识来算吧,好象有个什么拉格朗日展式,逐个展开,要多少位都可以的。

#2


哦,说错了,应该是泰勒展式。呵呵。
exp(x) = 1 + (x^1)/1! + (x^2)/2! + ... + (x^n)/n! + o(n) 
想办法编写一个循环,并且保证运算的精度,就可以了。

我们一般所使用的数据,精度是不可能保持在小数点后50000位的,所以,显示结果,可以用字符串的形式来返回。

#3


泰勒展式这东西是在百度搜的吧?我也看了。没看懂。呵呵。

#4



这东西能不能通过欧拉公式eiθ=cosθ+isinθ
算出来呢?

#5


就用泰勒展式就可以了
主要是你计算时控制精度的问题,最好用数组存放吧。

#6


谁能帮忙写下这个函数啊?应该不难吧?其实就写出来如何得到那个数就行。取小数点后50000的值那个应该不难实现

#7


引用 4 楼 shengli_liao 的回复:
这东西能不能通过欧拉公式eiθ=cosθ+isinθ 
算出来呢?

应该也可以,但是好像需要变换

#8


呵呵,程序会写,但是我并非数学专业,这个算法就难啦!

#9


数值分析学过 baidu下吧 呵呵

#10


高人在哪啊!

#11


引用 10 楼 wudiv998 的回复:
高人在哪啊!

这不是有人回答了吗?更多的你可以去查书呀,随便一本高等数学书上都有的。
引用 2 楼 preferme 的回复:
哦,说错了,应该是泰勒展式。呵呵。 
exp(x) = 1 + (x^1)/1! + (x^2)/2! + ... + (x^n)/n! + o(n) 
想办法编写一个循环,并且保证运算的精度,就可以了。 

我们一般所使用的数据,精度是不可能保持在小数点后50000位的,所以,显示结果,可以用字符串的形式来返回。 

#12


package sbTL;


class E {

public int setE(int i){
int sum = 1;
for(int j=i; j>0; j--){
sum = sum*j;
}
return sum;
}
public void getE(int i){
double sum=1;
for(int j=i; j>0; j--){
sum = sum + 1.0/setE(j);
}
System.out.println(sum);
}
}

public class SBTL{

public static void main(String[] args){
E e = new E();
e.getE(50000);

}
}
-------------------------------------------
Infinity

#13


import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.math.BigDecimal;

public class Test01 {

public static void main(String[] args) {

try {

int precision, i;
BufferedReader str = new BufferedReader(new InputStreamReader(
System.in));
System.out.println("输入整数:");
precision = Integer.parseInt(str.readLine());
str.close();

System.out.println("the e is :" + getE(precision+1).setScale(precision, BigDecimal.ROUND_FLOOR).toPlainString());
} catch (Exception e) {
e.printStackTrace();
}
}
/**
 * exp(1) = 1 + 1/1! + 1/2! + ... + 1/n!
 * @param precision
 * @return
 */
public static BigDecimal getE(int precision) {
BigDecimal one = BigDecimal.ONE;
BigDecimal value = BigDecimal.ONE;
BigDecimal n = BigDecimal.ONE;
BigDecimal factorial = BigDecimal.ONE;
BigDecimal lastValue = BigDecimal.ZERO;

while (true){
value = value.add(one.divide(factorial, precision, BigDecimal.ROUND_HALF_UP));
if (value.compareTo(lastValue) == 0) {
break;
} else if (value.compareTo(lastValue) < 0) {
System.out.println("???");
break;
}
n = n.add(one);
factorial = factorial.multiply(n);
lastValue = value;
}

return value;
}


}

#14


以上代码出来的结果有可能不正确
因为在对N的阶乘的倒数连续求和的过程中,所用的加数可能并不是精确的,
有可能累加的过程中出现误差。
快速的解决办法是:
在调用getE方法的时候,传一个更大的值进去;比如说,想用5000的小数,那么,传6000甚至更大,
这样应该可以消掉误差了;但代价是速度肯定会慢些。

至于具体用多少就能消误差,我不推不出来;如果有时间的话,这个5000的例子,可以多试几次测试出来。
我就不想花这个时间了,嘿嘿~

#15


补充说明,我所说的“具体用多少就能消误差”这个问题,一些数学高手应该可以算出来吧:
思路是,比如要N位小数,算出需要累加X次n阶乘的倒数,那么,相应的,用来消误差的位数应该是X的位数+1。
就是说,假如要5000位小数,如果要累加2000次的话,那么取2005位精度来运算足够了

#16


唉,本来想抛砖引玉一下的,怎么就没有人做出来呢。
LZ我给你写的那个表达式,你竟然看不懂么?
我写了一个,e的1次方的算法,给楼主提示一下,
如果要e的x次方的,可能要LZ自己编写了。
/**
 * 
 */
package houlei.test;

import java.math.BigDecimal;

/**
 * 
 *
 * 该类创建于 2008-9-22 下午01:31:44
 * @version 1.0.0
 * @author 侯磊
 */
public class H {

public static void main(String[] args) {
System.out.println(exp(20).toString());
}


/**
 * 该方法返回自然对数e的精确值。参数即为精确度(小数点后几位),
 * 速度比较慢。
 * @param scale 精确度
 * @return 返回自然对数e的精确值
 */
public static BigDecimal exp(int scale){
final BigDecimal a = new BigDecimal(1);
BigDecimal t = new BigDecimal(1);
BigDecimal sum = new BigDecimal(1);

for(int i=1;t.toString().length()<scale;i++){
 t = factorial(i);
 BigDecimal sub = a.divide(t,scale, BigDecimal.ROUND_HALF_UP);
sum=sum.add(sub);
}
return sum;
}

private static BigDecimal factorial(int n){
if(n<1)throw new IllegalArgumentException("参数必须为正整数");
BigDecimal tmp = new BigDecimal(1);
for(int i=2;i<=n;i++){
tmp=tmp.multiply(new BigDecimal(i));
}
return tmp;
}


}

#17



       /**
 * scale为自然对数e的精确度
 * @param args
 */
public static void main(String[] args) {
BigDecimal number = new BigDecimal(1);
BigDecimal value = new BigDecimal(1);
BigDecimal result = new BigDecimal(1);
int scale = 25000;
while(number.intValue() <= scale){
value = value.divide(number,scale,BigDecimal.ROUND_HALF_UP);
result = result.add(value);
number = number.add(BigDecimal.valueOf(1));
}
System.out.println(result);
}