60

最近、java.math.MathContextの使用法を理解しようとしましたが、正しく理解できませんでした。での丸めに使用されますかjava.math.BigDecimal。はいの場合、なぜそれは小数桁だけでなく仮数部分も丸めないのですか。

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

これについて何か考えがあれば教えてください。

4

5 に答える 5

76

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

たとえば、小数点以下3桁の数値を2桁の数値に変更し、切り上げます。

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

この結果は、値が1.24のBigDecimalになります(切り上げルールのため)

于 2010-11-16T12:55:27.560 に答える
53

@ジャタン

ご回答ありがとうございます。それは理にかなっている。BigDecimal#round メソッドのコンテキストで、MathContext について説明していただけますか。

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

精度は有効桁数を指定します。したがって、数値として指定123し、有効数字 2 桁を求めると、 が得られます120。科学表記法で考えると、より明確になるかもしれません。

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

このRoundingMode部分では、精度の低下を処理する方法を指定します。例を再利用するために、数値として使用123し、有効数字 2 桁を要求すると、精度が低下します。の(デフォルト モード) を使用すると、RoundingModeになります。の を使用すると、 が得られます。HALF_UP123120RoundingModeCEILING130

例えば:

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

精度と丸めモードの両方が出力に影響することがわかります。

于 2008-08-11T06:06:48.483 に答える
16

ここにいくつかの例を追加します。以前の回答ではそれらを見つけられませんでしたが、小数点以下の数で有効数字を誤解させる可能性がある人にとっては便利だと思います。そのようなコンテキストがあると仮定しましょう:

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桁に丸められません. 代わりに、最初の有効数字 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

これが明白であることを願っていますが、関連する例が役に立ちます...

于 2014-04-10T13:06:56.220 に答える
5

私があなたを正しく理解しているなら、あなたは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
于 2008-08-11T05:44:00.747 に答える
5

それは楽しみのためではありません。MathContext実際、BigDecimalに格納されている金額/数値を四捨五入するための使用法を示したオンラインの例をいくつか見つけました。

例えば、

を持つようにMathContext構成されている場合precision = 2rounding mode = ROUND_HALF_EVEN

BigDecimal Number = 0.52940.53に丸められます

それで、それは新しいテクニックだと思い、丸めの目的で使用しました。しかし、数のメンティッサ部分も丸め始めたため、悪夢になりました。

例えば、

Number = 1.5294に丸められます1.5

Number = 10.5294に丸められます10

Number = 101.5294に丸められます100

.... 等々

したがって、これは丸めに期待した動作ではありません(精度= 2として)。

パターンから、数値の最初の2桁(精度は2であるため)を取り、次に0をnoまで追加すると言うことができるので、何らかの論理があるようです。桁数は四捨五入されていない金額と同じになります(101.5294の例を確認してください...)

于 2008-08-11T05:45:35.173 に答える