56

緯度/経度に BigDecimal を使用する必要があるXSDがあります。私は現在、緯度/経度を double として持っており、それらを BigDecimal に変換していますが、約 12 桁の精度を使用する必要があるだけです。私はそれを設定する方法を理解することができませんでした。誰でもこれで私を助けることができますか?

4

4 に答える 4

98

たとえばsetScale()を使用できます

double d = ...
BigDecimal db = new BigDecimal(d).setScale(12, BigDecimal.ROUND_HALF_UP);
于 2012-02-28T13:40:43.840 に答える
45

質問のタイトルは精度について尋ねます。BigDecimalは位取りと精度を区別します。スケールは小数点以下の桁数です。精度は、有効数字とも呼ばれる有効数字の数と考えることができます。

Clojure でのいくつかの例。

(.scale     0.00123M) ; 5
(.precision 0.00123M) ; 3

(Clojure では、TheMは BigDecimal リテラルを示します。必要に応じて Clojure を Java に変換できますが、Java よりもコンパクトであることがわかります!)

スケールを簡単に増やすことができます:

(.setScale 0.00123M 7) ; 0.0012300M

ただし、まったく同じ方法でスケールを減らすことはできません。

(.setScale 0.00123M 3) ; ArithmeticException Rounding necessary

丸めモードも渡す必要があります。

(.setScale 0.00123M 3 BigDecimal/ROUND_HALF_EVEN) ;
; Note: BigDecimal would prefer that you use the MathContext rounding
; constants, but I don't have them at my fingertips right now.

そのため、スケールを変更するのは簡単です。しかし、精度はどうですか?これはあなたが期待するほど簡単ではありません!

精度を下げるのは簡単です:

(.round 3.14159M (java.math.MathContext. 3)) ; 3.14M

しかし、精度を上げる方法は明らかではありません。

(.round 3.14159M (java.math.MathContext. 7)) ; 3.14159M (unexpected)

懐疑的な人にとっては、これは末尾のゼロが表示されないという問題だけではありません。

(.precision (.round 3.14159M (java.math.MathContext. 7))) ; 6 
; (same as above, still unexpected)

FWIW、Clojureは末尾のゼロに注意しており、それら表示します:

4.0000M ; 4.0000M
(.precision 4.0000M) ; 5

軌道に戻る... BigDecimalコンストラクターを使用してみることができますが、指定した桁数よりも高い精度が設定されません。

(BigDecimal. "3" (java.math.MathContext. 5)) ; 3M
(BigDecimal. "3.1" (java.math.MathContext. 5)) ; 3.1M

そのため、精度を簡単に変更する方法はありません。この質問を書きながら、私が取り組んでいるプロジェクトで、これと戦うのに時間を費やしました。これはせいぜい CRAZYTOWN API であり、最悪の場合はバグだと思います。人々。真剣に?

したがって、精度を変更したい場合は、次の手順を実行する必要があります。

  1. 現在の精度を調べます。
  2. 現在のスケールを検索します。
  3. スケール変化を計算します。
  4. 新しい尺度を設定する

これらの手順は、Clojure コードとして:

(def x 0.000691M) ; the input number
(def p' 1) ; desired precision
(def s' (+ (.scale x) p' (- (.precision x)))) ; desired new scale
(.setScale x s' BigDecimal/ROUND_HALF_EVEN)
; 0.0007M

これは、精度を変更するためだけに多くの手順を踏む必要があることを知っています。

BigDecimal がまだこれを提供していないのはなぜですか? 私は何かを見落としましたか?

于 2013-12-04T01:43:08.020 に答える
4
 BigDecimal decPrec = (BigDecimal)yo.get("Avg");
 decPrec = decPrec.setScale(5, RoundingMode.CEILING);
 String value= String.valueOf(decPrec);

このようにして、特定の精度を設定できますBigDecimal

decPrec の値1.5726903423607562595809913132345426 は に四捨五入され1.57267ます。

于 2014-01-23T12:20:02.583 に答える
0

このコードを試してください...

    Integer perc = 5;
    BigDecimal spread = BigDecimal.ZERO; 
    BigDecimal perc = spread.setScale(perc,BigDecimal.ROUND_HALF_UP);
    System.out.println(perc);

結果: 0.00000

于 2016-07-11T12:02:24.417 に答える