6

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
4

8 に答える 8

13

doubleの代わりにBigDecimalを使用してください。

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)));
}
于 2009-09-26T18:10:22.423 に答える
6

あなたの主な問題は、double精度が非常に限られていることです。任意精度が必要な場合は、を使用する必要がありますBigDecimal。あなたが遭遇しようとしている次の問題はlong、階乗で非常に速く超えようとしている限られた範囲です-そこであなたは使うことができますBigInteger

于 2009-09-26T18:12:18.643 に答える
4

の任意精度演算を見ました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);
}
  }
}
于 2009-09-26T18:19:02.593 に答える
3

今のように1から49ではなく49から1まで数えると、より良い結果が得られます。

于 2009-09-26T18:11:13.653 に答える
1

パフォーマンスに関するアドバイスはありますか?

はい、階乗の計算は非常に非効率的です。項を合計しているループ内に移動することをお勧めします。あなたのやり方は、O(N) 問題を O(N^2) 問題に変えます。

これが階乗を必要とする実際の計算である場合は、テーブル ルックアップまたは不完全なガンマ関数を正しい方法としてお勧めします。

パフォーマンスの観点から、これよりも悪いことは、再帰的な階乗計算だけです。次に、巨大なスタックという追加の問題が発生します。

于 2009-09-26T20:27:16.860 に答える
1

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 
于 2009-09-26T20:09:35.357 に答える
0

で「任意の精度」が得られない理由を理解するにはdouble、次の古典的な論文を読んでください。

すべてのコンピューター科学者が浮動小数点演算について知っておくべきこと

これは非常に技術的な論文であることに注意してください。浮動小数点数の仕組みの基本的な詳細については、次の Wikipedia の記事を参照してください:倍精度浮動小数点形式

于 2009-09-26T19:15:54.680 に答える