分数和的计算精度 [英] Calculating precision of sum of fractions

查看:202
本文介绍了分数和的计算精度的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这个数学表达式:

∑(2k + 1)/(2k)!,k = 0,...,∞,它是所有分数从零到无穷大的和,形式为(2k + 1)/(2k)!

∑(2k+1)/(2k)! , k =0,... ,∞ , it is sum from zero to infinity of all fractions in the form (2k+1)/(2k)!

我想创建一个方法,当它传递整数"n"时,它将向我输出小数点后n位的结果.此表达式的前100位可以在此处查看:

I want to create a method which when passed an integer "n", it will output me the result with n digits after the decimal point.This expression first 100 digits can be viewed here : https://miniwebtool.com/first-n-digits-of-e/?number=100

这是我的代码,是我尝试过的

Here is my code, what I have attempted

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));

    }

}

问题在于,当我添加分数时,有时它们会溢出并在末尾创建额外的数字.如果使用strategy(6),它将输出多余的数字2.71828179,而不是2.718281

The problem is that when I add fractions, sometimes they will overflow and create extra digits at the end. In case of strategy(6) , it outputs extra digits 2.71828179 instead of 2.718281

对于strategy(5),它输出错误的答案2.7182787,而不是2.71828.任何想法他在哪里问题,如何将其正确地限制为精确输出?

In the case of strategy(5) it outputs wrong answer 2.7182787 instead of 2.71828. Any ideas where is he problem and how can I limit it correctly to output with precision?

推荐答案

您的代码存在的问题是,在每个步骤之后都对结果进行了四舍五入,因此对四舍五入的错误求和.

The problem with your code is that the result is being rounded after each step, and so rounding errors are being summed.

您应该使用Fraction类(例如此处描述的类): https://stackoverflow.com/a/474612 ),并在过程结束时提取小数表示.

You should use a Fraction class (such as the one described here: https://stackoverflow.com/a/474612) and extract the decimal representation at the end of the process.

编辑

我不是Java开发人员,所以我的计算机上没有设置适当的开发环境.我试图更新您的代码以使用之前链接的BigFraction类:

I'm not a Java developer, so I don't have a proper dev environment set up on my machine. I've tried to update your code to use the BigFraction class I linked earlier:

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重新计算.

It may be more efficient to refactor this code so that it doesn't use the factorial function or factorials are cached and don't have to be recomputed each time from 1.

这篇关于分数和的计算精度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆