web-dev-qa-db-ja.com

小数点以下2桁に四捨五入

値が200.3456である場合、それは200.34にフォーマットされるべきです。それが200であれば、それは200.00であるはずです。

413
Rajesh

これは、roundstruncating)の代わりに、指定された小数点以下の桁数に倍数するユーティリティです。

例えば:

round(200.3456, 2); // returns 200.35

元のバージョン;これで気をつけて

public static double round(double value, int places) {
    if (places < 0) throw new IllegalArgumentException();

    long factor = (long) Math.pow(10, places);
    value = value * factor;
    long tmp = Math.round(value);
    return (double) tmp / factor;
}

このは、非常に多くの小数点以下の桁数(例:round(1000.0d, 17))または大きな整数部(例:round(90080070060.1d, 9))のいずれかである場合に、ひどく破損します。これを指摘してくれた Sloin に感謝します。

私は何年もの間、「大きすぎない」ダブルを小数点以下2桁または3桁に丸めるために上記を使用していました(たとえば、ロギングの目的で時間を秒単位でクリーンアップするため:27.987654321987-> 27.99)。しかし、私はそれを避けるのが最善だと思います、なぜならよりクリーンなコードでも、より信頼できる方法がすぐに利用できるからです。

したがって、代わりにこれを使用してください

ルイワッサーマンによるこの回答 および この1つはショーンオーウェンによる から適応)

public static double round(double value, int places) {
    if (places < 0) throw new IllegalArgumentException();

    BigDecimal bd = BigDecimal.valueOf(value);
    bd = bd.setScale(places, RoundingMode.HALF_UP);
    return bd.doubleValue();
}

HALF_UPは「一般的に学校で教えられる」丸めモードであることに注意してください。 RoundingMode documentation をよく読んでください。 Bankers ’Rounding のような何か他のものが必要だと思われる場合。

もちろん、必要に応じて、上記を1行にインライン化できます。
new BigDecimal(value).setScale(places, RoundingMode.HALF_UP).doubleValue()

そして、あらゆる場合に

floatおよびdoubleを使用する浮動小数点表現はinexactであることを常に忘れないでください。たとえば、次の式を検討してください。

999199.1231231235 == 999199.1231231236 // true
1.03 - 0.41 // 0.6200000000000001

正確さのために、BigDecimalを使用したい。そして、その間に、文字列を受け取るコンストラクタを使用します。二重を取るコンストラクタは使用しないでください。たとえば、これを実行してみてください:

System.out.println(new BigDecimal(1.03).subtract(new BigDecimal(0.41)));
System.out.println(new BigDecimal("1.03").subtract(new BigDecimal("0.41")));

トピックに関するいくつかの優れたさらなる読書:


厳密に丸める数値の代わりに(またはそれに加えて)Stringformattingが必要な場合は、他の回答を参照してください。

特に、round(200, 0)200.0を返すことに注意してください。 「200.00」を出力する場合は、最初に結果を丸めてから出力用にフォーマットする必要があります(これは Jesperの答え で完全に説明されています)。

744
Jonik

小数点以下2桁のdoubleを印刷したいだけの場合は、次のようにします。

double value = 200.3456;
System.out.printf("Value: %.2f", value);

結果をコンソールに出力するのではなくStringにしたい場合は、同じ引数を付けてString.format()を使用します。

String result = String.format("%.2f", value);

あるいはクラスDecimalFormatを使う:

DecimalFormat df = new DecimalFormat("####0.00");
System.out.println("Value: " + df.format(value));
298
Jesper

これは簡単だと思います。

double time = 200.3456;
DecimalFormat df = new DecimalFormat("#.##");      
time = Double.valueOf(df.format(time));

System.out.println(time); // 200.35

これは実際には書式設定ではなく、あなたのために丸めをすることに注意してください。

113
Santiago

最も簡単な方法は、このようなトリックをすることです。

double val = ....;
val = val*100;
val = Math.round(val);
val = val /100;

valが200.3456で始まっている場合は、20034.56になり、それから20035に丸められてから、200.34になるように分割します。

あなたが常に切り捨てたいのであれば、intにキャストすることでいつでも切り捨てることができます。

double val = ....;
val = val*100;
val = (double)((int) val);
val = val /100;

非常に大きな倍精度(正または負)ではオーバーフローする可能性があるため、この手法はほとんどの場合に有効です。しかし、あなたの値が適切な範囲にあることを知っているなら、これはあなたのために働くはずです。

64
luke

Apache commons math :を使用してください。

Precision.round(10.4567, 2)
47
Pritesh Mhatre
function Double round2(Double val) {
    return new BigDecimal(val.toString()).setScale(2,RoundingMode.HALF_UP).doubleValue();
}

ToString()に注意してください。

これは、BigDecimalがdoubleの正確なバイナリ形式を変換するためです。

これらは提案されたさまざまな方法とそれらの失敗例です。

// Always Good!
new BigDecimal(val.toString()).setScale(2,RoundingMode.HALF_UP).doubleValue() 

Double val = 260.775d; //EXPECTED 260.78
260.77 - WRONG - new BigDecimal(val).setScale(2,RoundingMode.HALF_UP).doubleValue()

Double val = 260.775d; //EXPECTED 260.78
260.77 - TRY AGAIN - Math.round(val * 100.d) / 100.0d  

Double val = 256.025d; //EXPECTED 256.03d
256.02 - OOPS - new DecimalFormat("0.00").format(val) 
// By default use half even, works if you change mode to half_up 

Double val = 256.025d; //EXPECTED 256.03d
256.02 - FAIL - (int)(val * 100 + 0.5) / 100.0;
31
Luca Vix
double value= 200.3456;
DecimalFormat df = new DecimalFormat("0.00");      
System.out.println(df.format(value));
22
double d = 28786.079999999998;
String str = String.format("%1.2f", d);
d = Double.valueOf(str);
16
user1692711

あなたが本当に同じ倍精度が欲しいがあなたが望むように丸められているなら、あなたはBigDecimalを使うことができます、例えば

new BigDecimal(myValue).setScale(2, RoundingMode.HALF_UP).doubleValue();
13
daoway

二重に丸めることは、通常望んでいることではありません。代わりに、 String.format() を使用して目的の形式で表現してください。

丸め2桁の場合非常に単純で、あなたは基本的にDecimalFormatが行う表示目的の代わりに変数を更新しています。

x = Math.floor(x * 100) / 100;

6

あなたの質問では、それはあなたも数字を四捨五入しないようにしたいようですか?私は.format()がハーフアップを使用して数を丸めるだろうと思いますか?
したがって、丸めたい場合は、200.3456は2の精度で200.35になるはずですが、あなたの場合は、最初の2を使いたいだけで残りを捨てるのであれば、

これを100倍してからintにキャストする(または数値の下限を取る)ことができます。その後で再び100で割ります。

200.3456 * 100 = 20034.56;  
(int) 20034.56 = 20034;  
20034/100.0 = 200.34;

あなたは境界線の近くに本当に本当に大きな数の問題があるかもしれません。その場合、文字列に変換してそれを部分文字列化すると、同じように簡単に動作します。

0
bryanallott
value = (int)(value * 100 + 0.5) / 100.0;
0
user2068610