如何更优雅地编写代码? (Factorials,BigDecimals,BigIntegers划分)

时间:2017-04-09 13:26:19

标签: java math biginteger bigdecimal factorial

我已经设法使我的代码正常工作,但感觉有更好的方法来编写类似的东西,任何提示或错误指出?

这是我的代码:

  public static void main(String[] args) {
        DecimalFormat df = new DecimalFormat("0.##E0");
        BigDecimal a;
        BigInteger fact;
        int n=10;
        int x=3;

        for (int i=1; i<=n; i++){
            fact=BigInteger.valueOf(1);
            for (int j=1; j<=Math.pow(i,2)+1; j++){
            fact=fact.multiply(BigInteger.valueOf(j));
            }
        a=BigDecimal.valueOf((Math.pow(-1, i+1)*Math.log(i*x))/i).divide(new BigDecimal(fact), 500, BigDecimal.ROUND_HALF_EVEN);
        System.out.println(df.format(a));
        }
    }

Was calculating these numbers

1 个答案:

答案 0 :(得分:1)

我看到了以下改进:

  • 您可以从前一次迭代中的O(n^3)值开始,并将O(n^2)的缺失值相乘,从而将乘法次数从fact减少到j
  • 正如评论中所提到的,Math.pow(i,2)是一种过度杀伤力;同样适用于Math.pow(-1,i+1)
  • 使用BigDecimal.ONE

加上一些细微的变化,这给出了:

public static void main(String[] args) {
  DecimalFormat df = new DecimalFormat("0.##E0");
  int n = 10;
  int x = 3;
  int scale = 500;

  BigInteger fact = BigInteger.ONE;
  int rangeEndPrev = 0;
  int sign = 1;
  for (int i = 1; i <= n; i++)
  {
    int rangeEnd = i*i + 1;
    for (int j = rangeEndPrev + 1; j <= rangeEnd; j++)
      fact = fact.multiply(BigInteger.valueOf(j));
    BigDecimal a1 = BigDecimal.valueOf((sign * Math.log(i * x)) / i);
    BigDecimal a  = a1.divide(new BigDecimal(fact), scale, BigDecimal.ROUND_HALF_EVEN);
    System.out.println(df.format(a));
    rangeEndPrev = rangeEnd;
    sign = -sign;
  }
}