2008-08-11 13 views
42

最近、私はjava.math.MathContextの使用を理解しようとしましたが、正しく理解できませんでした。 java.math.BigDecimalで四捨五入に使用されていますか?そうだとしたら、小数点を丸めるのではなく、マティサの部分でも丸めます。java.math.MathContextの使用

APIドキュメントからは、ANSI X3.274-1996ANSI X3.274-1996/AM 1-2000の仕様に準拠していることがわかりましたが、私はそれらをオンラインで読むことはできませんでした。

これについてご意見がありましたら教えてください。

答えて

35

あなたが答えてくれてありがとう

@jatan。それは理にかなっている。 BigDecimal#roundメソッドの文脈でMathContextを説明してください。

についてBigDecimal.round()BigDecimal方法の特別なものは何もありません。すべての場合において、MathContextは有効桁数と丸め技法を指定します。基本的には、すべてMathContextの2つの部分があります。精度があり、RoundingModeもあります。

精度では、有効桁数が再度指定されます。したがって、数字として123を指定し、2桁の有効数字を尋ねると、120が得られます。あなたが科学的記法の面で考えるなら、それはもっと明白かもしれません。

123は、科学表記で1.23e2となる。有効数字が2桁しかない場合は、1.2e2または120となります。有効桁数を減らすことで、数値を指定できる精度が低下します。

RoundingMode部分は、精度の低下をどのように処理するべきかを指定します。この例を再利用するには、数字として123を使用し、2桁の有効数字を尋ねると、精度が低下しています。 RoundingModeHALF_UP(デフォルトモード)の場合、123120になります。 RoundingModeCEILINGの場合、130になります。例えば

System.out.println(new BigDecimal("123.4", 
        new MathContext(4,RoundingMode.HALF_UP))); 
System.out.println(new BigDecimal("123.4", 
        new MathContext(2,RoundingMode.HALF_UP))); 
System.out.println(new BigDecimal("123.4", 
        new MathContext(2,RoundingMode.CEILING))); 
System.out.println(new BigDecimal("123.4", 
        new MathContext(1,RoundingMode.CEILING))); 

出力:

123.4 
1.2E+2 
1.3E+2 
2E+2 

あなたは精度と丸めモードの両方が出力に影響を及ぼしていることがわかります。

+0

2有効数字を使用して '123.4 'をフォーマットする方法は、' 120'のような文字列になりますか?末尾のゼロは、末尾の10進数がない限り、重要な数字の検索に従来は含まれていないので、2桁の有効数字(「1.2E2」)です。そして、私の目的のために、フォーマットされる数字が '103.4 'だった場合、結果の' 100'の数字に2つのシグネチャがあるとは言えません。私はちょうど簡単/清潔な数字の表示をしたい。 – hepcat72

4

あなたが正しく理解している場合は、MathContextが小数点以下の桁数を制御することを期待しているようです。それはそれが何であるかではありません。保持する桁数を指定します。合計はです。したがって、有効数字3桁を指定すると、そのすべてが得られます。

たとえば、この:

System.out.println(new BigDecimal("1234567890.123456789", 
        new MathContext(20))); 

System.out.println(new BigDecimal("1234567890.123456789", 
        new MathContext(10))); 

System.out.println(new BigDecimal("1234567890.123456789", 
        new MathContext(5))); 

意志出力:

1234567890.123456789 
1234567890 
1.2346E+9 
+1

...私は、これは明らかに願っていますが、関連する例が参考になるありがとうございました。 10進数の後に保持する桁数はどのように選択できますか? – Drew

+1

これは本当にBigDecimalの質問ではありません。 BigDecimalでは、代わりに有効数字の数を指定する必要があります。ディスプレイの書式設定時に、小数点以下の桁数を決定する必要があります。これはString.format()またはDecimalFormat.format()で制御できます。 –

+0

@Drew私は[BigDecimal.setScale](http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/8u40-b25/java/math/BigDecimal.java#)を使うことができると思います。 BigDecimal.setScale%28int%2Cjava.math.RoundingMode%29)メソッドを呼び出します。最初のパラメータ(scale)は、小数点以下に保持する数値の数を指定し、2番目のパラメータ(roundingMode)は、必要な丸め動作を指定します。 –

4

はそれは楽しみのためではありません。実際には、MathContextを使用してBigDecimalに格納されている数値/数値を丸める方法を述べたオンラインの例がいくつか見つかりました。例えば

MathContextprecision = 2rounding mode = ROUND_HALF_EVEN

BigDecimal Number = 0.5294を持つように構成されている場合は、は、だから私はそれが新しい技術であると思ったとのためにそれを使用0.53

を丸めています丸めの目的。しかし、ナイトメアになったのは、ナンセンスの部分も丸め始めたからです。

例えば、

Number = 1.52941.5

Number = 10.5294に丸められるが10

Number = 101.5294に丸められるので

にだから100

に丸め....されこれは行動ではない私は丸め(precision = 2)を期待していました。

私は最初の2桁の数字(精度は2)を取り、その後0までを追加すると言うことができるので、何らかの論理を持っているようです。丸められていない量と同じになる数字の(... 101.5294の例をチェックアウト)

+1

だから、あなたは代わりに解決策を提案することができますか? –

52

BigDecimalの小数部を丸めるには、BigDecimal.setScale(int newScale, int roundingMode)メソッドをチェックしてください。

など。 2桁のいずれかに小数点以下3桁を持つ数を変更し、切り上げする:

BigDecimal original = new BigDecimal("1.235"); 
BigDecimal scaled = original.setScale(2, BigDecimal.ROUND_HALF_UP); 

この結果は、(なぜなら切り上げルールの)値1.24とのBigDecimalある

+15

これは、固定小数点数を使用して小数点以下の固定小数点数を維持する際に、人々が求めている答えです。 Sunがここで浮動小数点スタイルの「精度」をなぜバングルしたのか分からないが、それはMathContextと同じだ。 –

9

ここにいくつかの例を追加します。私は以前の答えでそれらを見つけられませんでしたが、私は小数点以下の桁数を誤解している人に役立つことがわかりました。さんはと仮定しましょう、私たちは、このような状況があります。このコードの場合

MathContext MATH_CTX = new MathContext(3, RoundingMode.HALF_UP); 

BigDecimal d1 = new BigDecimal(1234.4, MATH_CTX); 
System.out.println(d1); 

それはみんなが上記の言ったように、あなたの結果は1.23E+3であることを、完全に明らかです。最初の有効数字は123です...

しかし、この場合には:

BigDecimal d2 = new BigDecimal(0.000000454770054, MATH_CTX); 
System.out.println(d2); 

あなたの番号はコンマ後3ヶ所に四捨五入されることはありません - 誰かのためにそれは直感的で強調する価値がないことができます。代わりに、最初の有効数字のに丸められます。この場合は "4 5 4"です。したがって、上記のコード結果は4.55E-7になり、誰かが期待できるように0.000にはなりません。

同様の例:

BigDecimal d3 = new BigDecimal(0.001000045477, MATH_CTX); 
System.out.println(d3); // 0.00100 

BigDecimal d4 = new BigDecimal(0.200000477, MATH_CTX); 
System.out.println(d4); // 0.200 

BigDecimal d5 = new BigDecimal(0.000000004, MATH_CTX); 
    System.out.println(d5); //4.00E-9