1. ホーム
  2. java

[解決済み] doubleを小数点以下2桁に丸める[重複]。

2022-03-17 06:36:23

質問

もし値が 200.3456 にフォーマットされる必要があります。 200.34 . もし、それが 200 であれば、それは 200.00 .

解決方法は?

以下のようなユーティリティがあります。 ラウンド (代わりに 切り捨て ) を、指定された小数点以下の桁数で表示します。

例えば

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) ). おかげさまで スロイン ご指摘をいただきました。

私は何年も前から、quot;not so big" doubleを小数点以下2、3桁に丸めるのに使っています(例えば、ロギング用に秒単位の時間をクリーンアップする場合: 27.987654321987 -> 27.99 )。しかし、より信頼性の高い方法がすぐに利用でき、コードもよりきれいになるので、これを避けるのが最善だと思います。

だから、代わりにこれを使う

(からの転用です。 ルイス・ワッセルマン氏による回答 ショーン・オウエンの作品 .)

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のドキュメント のような他のものが必要だと思われる場合。 銀行員丸め .

もちろん、お望みであれば、上記をインライン化してワンライナーにすることも可能です。
new BigDecimal(value).setScale(places, RoundingMode.HALF_UP).doubleValue()

また、どのような場合でも

を使用した浮動小数点表現は、常に floatdouble 不正確 . 例えば、次のような表現を考えてみましょう。

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

正確さを求めるならBigDecimalを使いたい . そして、その間に、Stringを受け取るコンストラクタを使い、doubleを受け取るコンストラクタは使わないでください。例えば、次のように実行してみてください。

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

このトピックに関する優れた参考文献をいくつかご紹介します。


文字列が必要な場合 書式設定 数字を厳密に丸める代わりに(あるいはそれに加えて)、他の回答を参照してください。

具体的には、以下のことに注意してください。 round(200, 0) は以下を返します。 200.0 . もし、" を出力したい場合。 200.00 は、まず丸め、その結果をフォーマットして出力する必要があります(これについては Jesperの回答 ).