CodeGym /コース /JAVA 25 SELF /数値の丸めと書式設定

数値の丸めと書式設定

JAVA 25 SELF
レベル 6 , レッスン 4
使用可能

1. はじめに

現実の場面で、小数点以下に長い「しっぽ」のような桁を見たいことはあまりありません。たとえば、商品の価格、給料、平均点、部屋の面積などを計算する場合、ふつうは小数点以下数桁で十分で、15 桁も必要ありません。

たとえば、割り算の結果:

double x = 10.0 / 3.0;
System.out.println(x); // 3.3333333333333335

このような結果をユーザーが見ると、驚いてプログラムが壊れていると思うかもしれません。そこで数値はよく丸める必要があります——最も近い整数へ、小数点以下 2 桁へ、など。

Java にはそのための便利な手段がいくつか用意されています。

2. メソッド Math.round(): 最も近い整数への丸め

最も簡単な方法は、Math.round() メソッドを使うことです。浮動小数点数(float でも double でも可)を受け取り、最も近い整数を返します。

Math.round の動作

  • 小数部分が 0.5 未満なら切り捨て。
  • 小数部分が 0.5 以上なら切り上げ。

例:

System.out.println(Math.round(2.3)); // 2
System.out.println(Math.round(2.7)); // 3
System.out.println(Math.round(2.5)); // 3
System.out.println(Math.round(-2.5)); // -2

戻り値の型

  • float を渡すと、int を返します。
  • double を渡すと、long を返します。
float f = 5.8f;
int roundedF = Math.round(f); // 6

double d = 5.8;
long roundedD = Math.round(d); // 6

注意: double を丸めたのに long が返ってくるので驚くかもしれません。int が必要な場合は明示的にキャストします:

int rounded = (int) Math.round(5.6); // 6

3. 小数点以下の任意桁への丸め

整数ではなく、たとえば小数点以下 2 桁(通貨、パーセントなど)に丸めたいことはよくあります。

Java には「魔法の」Math.roundTo2Digits() のようなメソッドはありませんが、自分で実現できます。

方法 1: 乗算と除算を使う定番トリック

  1. 数値に 100 を掛ける(2 桁が必要な場合)。
  2. Math.round で整数に丸める。
  3. 元に戻すために 100 で割る。

例:

double value = 3.14159;
double rounded = Math.round(value * 100.0) / 100.0;
System.out.println(rounded); // 3.14

仕組み:

  • 3.14159 * 100 = 314.159
  • Math.round(314.159) = 314
  • 314 / 100.0 = 3.14

4. 数値の書式設定: クラス DecimalFormat

ときには丸めるだけでなく、特定の小数桁、先頭の 0、桁区切りなどで見やすく表示したいことがあります。これには Java の java.text パッケージにある DecimalFormat クラスを使います。

DecimalFormat の使い方

  1. 目的のパターンでオブジェクトを作成します。
  2. そのオブジェクトのメソッド format(...) を呼びます。
import java.text.DecimalFormat;

double value = 3.14159;

DecimalFormat df = new DecimalFormat("0.00");
System.out.println(df.format(value)); // 3.14

パターンの意味

  • "0.00" — 常に小数点以下 2 桁(整数でも 2 桁表示)。
  • "0.###" — 小数点以下最大 3 桁。余分な 0 は表示しない。
  • "#,##0.00" — 千位区切りを付ける(例: "1,234.56")。

さまざまなパターンの例:

パターン 数値 結果
"0.00"
2 2.00
"0.00"
2.5 2.50
"0.00"
2.567 2.57
"0.###"
2.567 2.567
"0.###"
2.5 2.5
"#,##0.00"
12345.678 12,345.68

千位区切りの例

DecimalFormat df = new DecimalFormat("#,##0.00");
System.out.println(df.format(1234567.89)); // 1,234,567.89

例: 余分な 0 を表示しない

DecimalFormat df = new DecimalFormat("0.##");
System.out.println(df.format(3.1));   // 3.1
System.out.println(df.format(3.141)); // 3.14
System.out.println(df.format(3.145)); // 3.15

5. String.format による書式設定

簡単なケースでは String.format を使うと便利です。他の言語における printf に似た組み込みの文字列書式化手段です。

double value = 3.14159;
System.out.println(String.format("%.2f", value)); // 3.14

ここで "%.2f" は「小数点以下 2 桁で表示する」という意味です。

アプローチの比較:

  • DecimalFormat — より強力。パターンとローカライズをサポートし、桁区切りに便利。
  • String.format — 小数桁数だけを指定したい場合に簡単。

6. 丸めの挙動の違い: Math.floor, Math.ceil, Math.rint

  • Math.floor(x) — 常に小さい方へ丸める(負の数でも同様)。
  • Math.ceil(x) — 常に大きい方へ丸める。
  • Math.rint(x) — 最も近い整数に丸めるが、戻り値は double

例:

System.out.println(Math.floor(2.7)); // 2.0
System.out.println(Math.ceil(2.1));  // 3.0
System.out.println(Math.rint(2.5));  // 2.0 (そう、誤りではありません!)
System.out.println(Math.rint(3.5));  // 4.0

注意: Math.rint はときどき「最も近い偶数」に丸めます。これは(いわゆる banker's rounding、偶数丸め)で、多数の計算における誤差の蓄積を抑えるのに役立ちます。

7. 便利な補足

可視化: 丸めの比較表

数値 Math.round Math.floor Math.ceil Math.rint
2.3 2 2.0 3.0 2.0
2.5 3 2.0 3.0 2.0
3.5 4 3.0 4.0 4.0
-2.3 -2 -3.0 -2.0 -2.0
-2.5 -2 -3.0 -2.0 -2.0

丸めは書式設定ではありません!

丸め書式設定 の違いを理解することがとても重要です。

  • 丸め — 数値そのものの値を変更する(例: 2.7182.72)。
  • 書式設定 — 表示の見た目だけを変える(例: 2.718 → 画面上は "2.72" だが、メモリ上の値は 2.718 のまま)。
double x = 2.718;
System.out.println(String.format("%.2f", x)); // 2.72
System.out.println(x); // 2.718

以降の計算で丸めた値を使いたいなら、数学的に丸めてください。表示だけが目的なら、書式設定を使いましょう。

8. 丸めと書式設定でよくある誤り

誤り 1: 表示だけ丸めて、以降は「長い小数」のまま使ってしまう。
よくあるのは、画面にはきれいに書式設定した値を表示する一方で、計算には元の「長い」数値を使ってしまうケースです。金額、スコア、集計などでは、まず丸め(たとえば Math.round や乗算/除算の手法)を行い、その値を保存・ユーザーに渡してください。

誤り 2: Math.round(x) が小数点以下 2 桁の double を返すと思い込む。
Math.round() は常に最も近い整数に丸めます。float には intdouble には long を返します。小数点以下 2 桁にしたい場合は、乗算/除算や書式設定を使いましょう。

誤り 3: 計算に DecimalFormat を使う。
DecimalFormat.format() は文字列を返します。これを算術に使うことはできません。コンパイルエラーになるか、逆に数値へパースする際に NumberFormatException が発生します。

誤り 4: DecimalFormat のパターンを誤る。
意図に合ったパターンを選びましょう。"0.00" は常に 2 桁を表示("2.00")、"0.##" は余分な 0 を省きます("2""2.1""2.12")。

誤り 5: 100 で割るときの整数除算。
intint で割ると、結果も int です!

int a = 5;
System.out.println(a / 2); // 2(2.5 ではありません!)

小数の除算にするには、少なくとも一方を double にします:

int a = 5;
System.out.println(a / 2.0); // 2.5
コメント
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION