Java 分数和的计算精度
我有一个数学表达式: ∑(2k+1)/(2k),k=0,∞ , 它是(2k+1)/(2k)形式中所有分数从零到无穷的和 我想创建一个方法,当传递一个整数“n”时,它将输出小数点后有n位的结果。可以在此处查看前100位的表达式: 这是我的代码,我已经尝试过了Java 分数和的计算精度,java,algorithm,math,Java,Algorithm,Math,我有一个数学表达式: ∑(2k+1)/(2k),k=0,∞ , 它是(2k+1)/(2k)形式中所有分数从零到无穷的和 我想创建一个方法,当传递一个整数“n”时,它将输出小数点后有n位的结果。可以在此处查看前100位的表达式: 这是我的代码,我已经尝试过了 package pi.strategy; import java.math.BigDecimal; import java.math.BigInteger; import java.math.RoundingMode; import jav
package pi.strategy;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.math.RoundingMode;
import java.util.stream.IntStream;
import java.util.stream.LongStream;
public class Tester {
public static BigInteger factorial(long k) {
return LongStream.range(2, k + 1).mapToObj(BigInteger::valueOf).reduce(BigInteger.ONE,
(current, factSoFar) -> factSoFar.multiply(current));
}
protected static BigDecimal strategy(int precision) {
return IntStream.range(0, precision).mapToObj(i -> computeMember(i, precision + 2))
.reduce(BigDecimal.ZERO, (current, sumSoFar) -> sumSoFar.add(current));
}
static BigDecimal computeMember(int n, int scale) {
final BigDecimal dominator = new BigDecimal((2 * n) + 1);
final BigDecimal enumenator = new BigDecimal(factorial(2 * n));
// System.out.println("Temp Result:" + dominator.divide(enumenator, scale,
// RoundingMode.HALF_UP));
BigDecimal res = dominator.divide(enumenator, scale, RoundingMode.HALF_UP);
return res;
}
public static void main(String... args) {
System.out.println(strategy(6));
}
}
问题是,当我添加分数时,有时它们会溢出,并在末尾创建额外的数字。
对于策略(6),它输出额外的数字2.71828179,而不是2.718281
对于策略(5),它输出错误答案2.7182787,而不是2.71828。你知道问题出在哪里吗?我怎样才能正确地将其限制为精确的输出?你的代码的问题是,结果在每一步后都被舍入,因此舍入误差被求和 您应该使用一个分数类(比如这里描述的:)并在过程结束时提取十进制表示 编辑 我不是Java开发人员,所以我没有在我的机器上设置合适的开发环境。我已尝试更新您的代码以使用我先前链接的BigFraction类:
package pi.strategy;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.math.RoundingMode;
import java.util.stream.IntStream;
import java.util.stream.LongStream;
public class Tester {
public static BigInteger factorial(long k) {
return LongStream.range(2, k + 1).mapToObj(BigInteger::valueOf).reduce(BigInteger.ONE,
(current, factSoFar) -> factSoFar.multiply(current));
}
protected static BigFraction strategy(int precision) {
return IntStream.range(0, precision).mapToObj(i -> computeMember(i, precision + 2))
.reduce(BigFraction.ZERO, (current, sumSoFar) -> sumSoFar.add(current));
}
static BigFraction computeMember(int n, int scale) {
final BigDecimal numerator = new BigDecimal((2 * n) + 1);
final BigDecimal denominator = new BigDecimal(factorial(2 * n));
return new BigFraction(numerator, denominator);
}
public static void main(String... args) {
final BigFraction result = strategy(6);
System.out.println(result);
System.out.println(result.toBigDecimal());
}
}
重构此代码可能更有效,这样它就不会使用阶乘函数,或者阶乘被缓存,并且不必从1开始每次重新计算。这是否回答了您的问题?不,不是真的,我正试图在运行时停止加法。想象一下,如果计算整数需要1小时,而你只需要前5位或前10位。这是我的目标,当我们达到精度时停止计算。如果在运行时停止加法是你的目标,你应该投资数学。要计算给定精度需要多少项,请查看泰勒定理,特别是在。