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: 乗算と除算を使う定番トリック
- 数値に 100 を掛ける(2 桁が必要な場合)。
- Math.round で整数に丸める。
- 元に戻すために 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 の使い方
- 目的のパターンでオブジェクトを作成します。
- そのオブジェクトのメソッド 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")。
さまざまなパターンの例:
| パターン | 数値 | 結果 |
|---|---|---|
|
2 | 2.00 |
|
2.5 | 2.50 |
|
2.567 | 2.57 |
|
2.567 | 2.567 |
|
2.5 | 2.5 |
|
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.718 → 2.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 には int、double には long を返します。小数点以下 2 桁にしたい場合は、乗算/除算や書式設定を使いましょう。
誤り 3: 計算に DecimalFormat を使う。
DecimalFormat.format() は文字列を返します。これを算術に使うことはできません。コンパイルエラーになるか、逆に数値へパースする際に NumberFormatException が発生します。
誤り 4: DecimalFormat のパターンを誤る。
意図に合ったパターンを選びましょう。"0.00" は常に 2 桁を表示("2.00")、"0.##" は余分な 0 を省きます("2"、"2.1"、"2.12")。
誤り 5: 100 で割るときの整数除算。
int を int で割ると、結果も int です!
int a = 5;
System.out.println(a / 2); // 2(2.5 ではありません!)
小数の除算にするには、少なくとも一方を double にします:
int a = 5;
System.out.println(a / 2.0); // 2.5
GO TO FULL VERSION