1

算術式を使用したビジネスロジックがいくつかあり、その結果は次のとおりです

(10.0 * 20.58)/1.0=205.7999..98
(6.0 * 37.9)/1.0=227.3999..98
(5.0 * 50.0)/1.0=250.0
(10.0 * 37.9)/1.0=379.0

しかし、期待される結果は

(10.0 * 20.58)/1.0=205.8
(6.0 * 37.9)/1.0=227.4
(5.0 * 50.0)/1.0=250.0
(10.0 * 37.9)/1.0=379.0

.999..98 の小数部を取得する理由がよくわかりません。そのため、equals 比較が失敗し、ビジネス ロジックが失敗します。私たちが使用しているいくつかのケースでは

amt = (double)Math.round(orderAmt*100000)/100000;

しかし、二重の算術式があるすべての場所で同じことを行うことはできません。

このような結果がランダムに得られる理由を知りたいのですが、すべての場所を丸めるのではなく、結果を小数点以下 5 桁に丸める可能性はありますか?

4

5 に答える 5

1

BigDecimal丸めに使用できます

BigDecimal bd = new BigDecimal((10.0 * 20.58)/1.0) ;
bd = bd.setScale(4, RoundingMode.UP);

静的メソッドで使用する

public static double round(double value, int digits) {
    BigDecimal bd = new BigDecimal(value);
    return bd.setScale(digits, RoundingMode.UP).doubleValue();
}

RoundingModeもっている :

RoundingMode.UP;
RoundingMode.DOWN;
RoundingMode.HALF_DOWN;
RoundingMode.HALF_EVEN;
于 2012-11-15T14:15:31.220 に答える
1

基本的な問題は、

System.out.println(10.0 * 20.58);

版画

205.79999999999998

の表現誤差による小さな丸め誤差があります20.58

あなたはする必要があります

  • 比較する前に結果を丸めます。
  • 多少の誤差を許容する比較を使用する
  • BigDecimal を使用します (ほとんどの場合、オーバーキルです)。
  • ドルの代わりにセントを使用します。つまり、固定精度のintorを使用します。long

最後のケースでは、同じ操作で次のようになります。

System.out.println(10 * 2058);

版画

20580

ここで、これは、ドルではなくセントなど、固定精度として必要な値の 100 倍です。

于 2012-11-15T14:46:19.013 に答える
1

基数 10 では、1/3 = 0.33333333... のように、有限の桁数で正確に表現できない分数がいくつかあります。

基数 2 の場合も同じですが、この種の結果を生成する除算器は慣れ親しんだものではありません。たとえば、20.58 の場合は 2058 / 100 が当てはまります。

内部的には、double と float はビット (非数字) で格納されるため、double または float の正確な値をコンピュータのメモリに格納することはできません。この値を使用して操作を実行するたびに、近似のために小さなシフトが発生します。これは、印刷用に 10 進形式に変換し直すときに表示されます。

これは、精度が重要な計算を実行する際に注意しなければならないことです。

したがって、2 つの解決策があります。

  • すべての数値を 10 進型で保存し、それを使用してすべての計算を実行します。これにより精度が達成されますが、パフォーマンスは犠牲になります。
  • また、すべての計算を double または float で保持し、結果を印刷するためだけに固定桁数でフォーマットすることもできます。
于 2012-11-15T14:50:14.863 に答える
0

double以下のように丸めを使用することができます。

    double roundingPlaces = 10.0;//use 10.0 for single decimal digit rounding
    double a1 = 10.0;
    double b1 = 20.58;
    double c1 = 1.0;
    System.out.println(Math.round((a1*b1*roundingPlaces)/c1)/roundingPlaces);

これは 205.8 を出力します。

    float fa1 = (float) 10.0;
    float fb1 = (float)20.58;
    float fc1 = (float)1.0;
    System.out.println(fa1*fb1/fc1);    

これも205.8を出力します

于 2012-11-15T14:25:46.343 に答える
0

floatの代わりに使用double

http://ideone.com/L9vwR8

System.out.println((float)((10.0f * 20.58f)/1.0f));

出力

205.8

于 2012-11-15T14:21:18.730 に答える