私はJavaで通貨換算アプリを作っています。他のいくつかの素晴らしいStackOverflowiansは私に任意の精度の問題を修正するために、二重の交換を目的としてBigDecimalの上に読み込むためのアドバイスを与えました。
私は2つの方法でシステムを持っています。それはUSDに起動通貨から変換場合、宛先通貨にUSD値を変換します。
注、私のコンバージョン率は、次のように格納されます。
// Conversion Rates - START (as of October 30, 2018 @ 3:19 AM)
// Rates obtained from exchange-rates.org
//Convert to United States Dollar rates
private final BigDecimal CAD_TO_USD = new BigDecimal(0.76135);
private final BigDecimal EUR_TO_USD = new BigDecimal(1.1345);
private final BigDecimal YEN_TO_USD = new BigDecimal(0.008853);
// Conversion Rates - END
私は、それぞれのBigDecimalと私のダブルスを交換した後 - 私はそれをテストし、それがすべてうまくいく方法を確認することにしました。
私のテスタークラスには、変換プロセスを開始するには、次の方法を実行します。
public BigDecimal convert()
{
BigDecimal value;
value = convertToUSD(); //Converts the current currency into USD
value = convertFromUSD(value); //Converts the previous USD currency value into the destination currency
return value;
}
私は(カナダドルに2.78円を変換している)私のサンプル変数を入力すると、私は、プロセスを通じて段階と、私は値を返すまで、そのすべての機能をアップしました。
前述の方法から、convertToUSD()
実行されると、次のようにコーディングされています
private BigDecimal convertToUSD()
{
switch (fromCurrency)
{
case "USD":
return fromQuantity.multiply(new BigDecimal(1));
case "CAD":
return fromQuantity.multiply(CAD_TO_USD);
case "EUR":
return fromQuantity.multiply(EUR_TO_USD);
case "YEN":
return fromQuantity.multiply(YEN_TO_USD);
}
return new BigDecimal(0);
}
すべての値が正しく渡され、それが適切な場合(「円」)へのダウンを通じて段階的に説明し、「fromQuantity」のBigDecimalは(私には理にかなって)278のintCompact値を持っていることを、変数ペインショー
すぐにブレークポイントを返しますが、「変換」方法にバックアップとして、それはすべてが台無しになります。代わりに返す2.78 * 0.008853 = 0.0246
、それが返されます-9223372036854775808
。
これは、生産とエラーに他のすべての計算が発生します。
私はBigDecimalの使用に新しいですので、私は完全に明白な間違いを犯してすることができます。私は学ぶことが幸せですので、私はあなたたちからアドバイスを求め:)
どのような援助が理解されます。
TL; DR
使用することはString
、ありませんdouble
リテラル。
new BigDecimal( "2.78" ) // Pass "2.78" not 2.78
.multiply(
new BigDecimal( "0.008853" ) // Pass "0.008853" not 0.008853
)
.toString()
0.02461134
浮動小数点型を渡さないでください
ポイントBigDecimal
クラスは避けることである固有の不正確で見つかった浮動小数点テクノロジを。浮動小数点型などのfloat
/ Float
とdouble
/ Double
実行速度精度を離れて取引。これとは対照的に、BigDecimal
ゆっくりではあるが正確です。
あなたのコード:
new BigDecimal( 0.76135 )
new BigDecimal( 1.1345 )
new BigDecimal( 0.008853 )
...通過しているdouble
プリミティブリテラルを。コンパイル時には、あなたが入力したテキストは0.76135
、具体的として、数として解析されdouble
(64ビット浮動小数点値)。その時点で、このタイプの固有の不正確を導入しています。言い換えると、double
から生産は0.76135
もはや正確にないかもしれません0.76135
。
さんがあなたのダンプしてみましょうBigDecimal
すぐにインスタンス化した後にインスタンスを。
System.out.println( new BigDecimal( 0.76135 ) ); // Passing a `double` primitive.
System.out.println( new BigDecimal( 1.1345 ) );
System.out.println( new BigDecimal( 0.008853 ) );
0.7613499999999999712230192017159424722194671630859375
1.13450000000000006394884621840901672840118408203125
0.0088529999999999997584154698415659368038177490234375
だから、作成することにより、double
数値を、あなたは、浮動小数点の技術を呼び出し、および不正確さを紹介しました。
使用文字列
ソリューション?回避文字列での作業、double
完全にタイプを。
いくつか入れてこれらの入力の周りに二重引用符を、そして出来上がり。
System.out.println( new BigDecimal( "0.76135" ) ); // Passing a `String` object.
System.out.println( new BigDecimal( "1.1345" ) );
System.out.println( new BigDecimal( "0.008853" ) );
0.76135
1.1345
0.008853
例
あなたは期待しました2.78 * 0.008853 = 0.0246
。試してみよう。
BigDecimal x = new BigDecimal( "2.78" );
BigDecimal y = new BigDecimal( "0.008853" );
BigDecimal z = x.multiply( y );
System.out.println( x + " * " + y + " = " + z );
2.78 * 0.008853 = 0.02461134
次は丸め&と切り捨て上に勉強しなければなりませんBigDecimal
。すでにスタックオーバーフローに何度もカバーしました。