読み込み中...

Javaで四捨五入する方法を10の実例で徹底解説

Javaプログラミングを学ぶ人が画面を見つめ、四捨五入の方法を学ぶイラスト Java
この記事は約13分で読めます。

【サイト内のコードはご自由に個人利用・商用利用いただけます】

この記事では、プログラムの基礎知識を前提に話を進めています。

説明のためのコードや、サンプルコードもありますので、もちろん初心者でも理解できるように表現してあります。

本記事のサンプルコードを活用して機能追加、目的を達成できるように作ってありますので、是非ご活用ください。

※この記事は、一般的にプロフェッショナルの指標とされる『実務経験10,000時間以上』を満たす現役のプログラマチームによって監修されています。

※Japanシーモアは、常に解説内容のわかりやすさや記事の品質に注力しております。不具合、分かりにくい説明や不適切な表現、動かないコードなど気になることがございましたら、記事の品質向上の為にお問い合わせフォームにてご共有いただけますと幸いです。
(送信された情報は、プライバシーポリシーのもと、厳正に取扱い、処分させていただきます。)

●なぜJavaで四捨五入が必要?

プログラミングをしていると、小数点以下の値を丸めたいシーンに遭遇することがよくあります。

例えば、金額計算や単位の変換など、数値を扱う処理では四捨五入が欠かせません。

○四捨五入の基本的な考え方

四捨五入とは、端数を丸めて整数値にする処理のことです。

一般的には、小数点以下の値が0.5以上なら切り上げ、0.5未満なら切り捨てるルールで丸められます。

この方法なら、丸め誤差を最小限に抑えられるでしょう。

○Javaにおける四捨五入の重要性

Javaは高い数値計算能力を持つプログラミング言語ですが、四捨五入処理一つとっても奥が深いのです。

状況に応じて適切な丸め方を選択しないと、思わぬ不具合を引き起こしかねません。

例えば、金額計算で四捨五入を怠ると、わずかな誤差が蓄積されて大きな間違いにつながる恐れがあります。

また、単位変換時に適切な桁数で丸めないと、データの精度が失われてしまうかもしれません。

だからこそ、Javaエンジニアは四捨五入の様々な方法を習得し、シーンに合わせて使い分ける技術が求められるのです。

正確で効率的なコードを書くには、四捨五入処理の重要性を再認識することが大切ですね。

●Math.round()を使った四捨五入

では、具体的にJavaで四捨五入を実装する方法を見ていきましょう。

まずは、Javaの標準ライブラリに用意されているMath.round()メソッドを見ていきましょう。

○サンプルコード1:小数点以下を四捨五入して整数化

Math.round()は引数に渡した数値を四捨五入し、長整数型の値を返します。

小数点以下を丸めて整数化したいときに便利です。

double value = 3.14;
long roundedValue = Math.round(value);
System.out.println(roundedValue);

実行結果

3

小数点以下を四捨五入して整数値が得られましたね。

このように、Math.round()を使えば簡単に値を丸められます。

○サンプルコード2:小数点第1位で四捨五入

でも、小数点第1位で丸めるにはどうすればいいのでしょうか。

実は、Math.round()と少し工夫を組み合わせるだけで実現できます。

double value = 3.14;
double roundedValue = Math.round(value * 10.0) / 10.0;
System.out.println(roundedValue);

実行結果

3.1

10倍して整数化した後、10で割ることで小数点第1位での丸めを実現しています。

こうした小テクニックを使いこなせば、Math.round()の用途が広がりそうです。

○サンプルコード3:任意の桁数で四捨五入

さらに、任意の桁数で丸めたい場合はどうすればいいのでしょうか。

そのときは、10の累乗を使った汎用的な方法がおすすめです。

double value = 123.456;
int scale = 2; // 丸める桁数
double shift = Math.pow(10, scale);
double roundedValue = Math.round(value * shift) / shift;
System.out.println(roundedValue);

実行結果

123.46

Math.pow()で10の累乗を計算し、任意の桁数に対応しています。

これなら、様々なケースで四捨五入処理が行えそうですね。

●BigDecimalを使った四捨五入

Math.round()は便利ですが、より高度な四捨五入処理を実現するには物足りないと感じたことはありませんか?

特に、金融システムなど厳密な計算が求められる場面では、もっと信頼できる方法が必要ですよね。

そんなときは、JavaのBigDecimalクラスを使うのがおすすめです。

BigDecimalは不変の浮動小数点数を表現するクラスで、高精度な数値計算に適しています。

四捨五入処理もBigDecimalなら安心して任せられます。

○サンプルコード4:setScaleメソッドによる四捨五入

BigDecimalで四捨五入を行うには、setScaleメソッドを使います。

第1引数で小数点以下の桁数、第2引数で丸めモードを指定できるので、細かい制御が可能です。

BigDecimal value = new BigDecimal("123.456");
BigDecimal roundedValue = value.setScale(2, RoundingMode.HALF_UP);
System.out.println(roundedValue);

実行結果

123.46

setScaleメソッドは、指定された桁数で丸めた新しいBigDecimalインスタンスを返します。

元の値は変更されないので、安全に使えます。

ここでは、HALF_UPモードで四捨五入していますが、他にも切り上げや切り捨てなど様々な丸めモードが選べます。

○サンプルコード5:divideメソッドとRoundingModeの組み合わせ

BigDecimalの四捨五入には、divideメソッドを使う方法もあります。

これは、2つのBigDecimal値の割り算と丸め処理を一緒に行えます。

BigDecimal value1 = new BigDecimal("10");
BigDecimal value2 = new BigDecimal("3");
BigDecimal result = value1.divide(value2, 2, RoundingMode.HALF_UP);
System.out.println(result);

実行結果

3.33

divideメソッドの第3引数で小数点以下の桁数、第4引数で丸めモードを指定します。

割り算の結果を任意の桁数で丸められるので、柔軟性の高い四捨五入処理が実現できますね。

○RoundingModeの種類と違い

BigDecimalの丸めモードは、列挙型のRoundingModeで定義されています。

よく使われるモードをいくつか紹介しましょう。

  • ROUND_UP -> 常に切り上げ
  • ROUND_DOWN -> 常に切り捨て
  • HALF_UP -> 五捨六入(0.5以上は切り上げ、未満は切り捨て)
  • HALF_DOWN -> 六捨五入(0.5超は切り上げ、以下は切り捨て)
  • HALF_EVEN -> 偶数丸め(丸めた後の値が偶数になるように丸める)

状況に応じて適切なモードを選ぶことが大切です。

例えば、金額計算ではHALF_EVENを使うと丸め誤差を最小限に抑えられます。

一方、切り上げや切り捨てが必要なケースもあるでしょう。

BigDecimalとRoundingModeを使いこなせば、シーンに合わせた柔軟な四捨五入処理が実装できます。

ただし、BigDecimalは少し冗長な記述が必要で、学習コストもかかります。

用途に応じてMath.round()と使い分けるのが賢明です。

●その他の四捨五入メソッド

Math.round()やBigDecimalを使えば、ほとんどの四捨五入処理は事足りるでしょう。

でも、状況によってはもっと特殊な丸め方が必要になることもあります。

そんなときのために、Javaには他にも便利な四捨五入メソッドが用意されています。

ここでは、そんな隠れた実力者たちを紹介しましょう。きっとあなたのコーディングの引き出しが増えるはずです。

○サンプルコード6:Math.ceil()で切り上げ

Math.ceil()は、引数の値以上の最小の整数を返すメソッドです。

つまり、小数点以下を切り上げて整数化してくれます。

double value = 3.14;
double ceiledValue = Math.ceil(value);
System.out.println(ceiledValue);

実行結果

4.0

Math.ceil()を使えば、端数があるときは必ず繰り上がるような処理が実装できます。

在庫管理システムで、必要数量を計算するようなケースでは重宝するでしょう。

ただし、Math.ceil()の戻り値は常にdouble型になります。

intやlong型が欲しい場合は、キャストが必要なので注意が必要ですね。

○サンプルコード7:Math.floor()で切り捨て

Math.floor()は、Math.ceil()の反対で、引数の値以下の最大の整数を返します。

つまり、小数点以下を切り捨てて整数化するメソッドです。

double value = 3.14;
double flooredValue = Math.floor(value);
System.out.println(flooredValue);

実行結果

3.0

Math.floor()は、端数を無視して整数部分だけ取り出したいときに便利です。

例えば、割引計算で端数を切り捨てるような処理が実装できます。

Math.floor()の戻り値もdouble型なので、他の整数型が必要なときはキャストを忘れずに。

○サンプルコード8:独自の四捨五入メソッドを実装

標準ライブラリだけでは要件を満たせないこともあります。

そんなときは、自前の四捨五入メソッドを実装するのも一つの手です。

例えば、小数点以下2桁を超える部分は切り捨て、2桁目が5以上なら1桁目を繰り上げるといったルールの丸め処理を作ってみましょう。

public static double roundCustom(double value) {
    value *= 100; // 小数点以下2桁目まで残す
    long round = Math.round(value); // 四捨五入
    double result = (double)round / 100; // 小数点以下2桁目まで戻す
    return result;
}

このメソッドを使ってみます。

double value = 123.456;
double roundedValue = roundCustom(value);
System.out.println(roundedValue);

実行結果

123.46

独自ルールの四捨五入ができましたね。

汎用的なユーティリティメソッドとして切り出しておけば、プロジェクト全体で共通利用できます。

コード品質の向上に繋がるでしょう。

もちろん、要件によって実装は様々。状況に応じて柔軟に対応できるのが、プログラマの腕の見せ所ですからね。

四捨五入処理は奥が深いですが、Javaなら様々な実現方法があります。

状況に合わせて適切なメソッドを選択し、可読性や保守性の高いコードを書くことが大切です。

●四捨五入でよくあるエラーと対処法

四捨五入処理を実装していると、思わぬところでエラーに遭遇することがありますよね。

特に、初心者のうちは原因の特定に苦労するものです。

でも、大丈夫。よくあるエラーとその対処法を知っておけば、問題解決の糸口が見つかります。

ここでは、四捨五入でよく発生するエラーを取り上げ、その原因と対策を探っていきましょう。

○丸め誤差への対処方法

四捨五入処理で最もよく遭遇するのが、丸め誤差の問題ではないでしょうか。

特に、浮動小数点数を扱う場合、思わぬ結果になることがあります。

double value = 2.675;
double rounded = Math.round(value * 100) / 100.0;
System.out.println(rounded); // 2.67と表示される

ここでは、2.675を小数点第2位で四捨五入しているつもりですが、実際には2.67になってしまいました。

これは、浮動小数点数の仕様に起因する誤差です。

こうした丸め誤差を防ぐには、BigDecimalを使うのが確実です。

BigDecimalなら、厳密な計算が可能ですからね。

BigDecimal value = new BigDecimal("2.675");
BigDecimal rounded = value.setScale(2, RoundingMode.HALF_UP);
System.out.println(rounded); // 2.68と表示される

BigDecimalを使えば、期待通りの結果が得られました。

金額計算など、厳密な値が求められる場面では、BigDecimalを活用するようにしましょう。

○ArithmeticExceptionへの対処方法

BigDecimalを使った四捨五入処理で、時々ArithmeticExceptionが発生することがあります。

BigDecimal value = new BigDecimal("1.0");
BigDecimal divisor = new BigDecimal("3");
BigDecimal result = value.divide(divisor); // ArithmeticExceptionが発生

これは、割り切れない除算を行ったことが原因です。

こうしたケースでは、divideメソッドの第2引数で丸めモードを指定する必要があります。

BigDecimal value = new BigDecimal("1.0");
BigDecimal divisor = new BigDecimal("3");
BigDecimal result = value.divide(divisor, 2, RoundingMode.HALF_UP);
System.out.println(result); // 0.33と表示される 

丸めモードを指定することで、例外を回避できました。

BigDecimalの除算では、必ず丸めモードを設定するクセをつけておくと良いでしょう。

●四捨五入の応用例

ここまで、Javaにおける四捨五入の様々な方法を見てきました。

でも、実際の開発現場ではどんなシーンで四捨五入が使われているのでしょうか。

せっかく学んだ知識も、実践で活用してこそ真価を発揮します。

ここでは、四捨五入処理が役立つ具体的なユースケースを紹介しましょう。

きっと、皆さんの開発にもヒントになるはずです。

○サンプルコード9:金額計算での四捨五入

金額計算は、四捨五入処理が欠かせない代表的なシーンですね。

例えば、消費税の計算では端数処理が必要です。

BigDecimal price = new BigDecimal("1000");
BigDecimal taxRate = new BigDecimal("0.08");
BigDecimal tax = price.multiply(taxRate).setScale(0, RoundingMode.HALF_UP);
System.out.println(tax); // 80と表示される

ここでは、消費税率8%として計算しています。

BigDecimalを使って金額と税率を掛け合わせた後、setScaleメソッドで小数点以下を四捨五入しています。

金額計算では、丸め誤差が許容されないケースが多いので、BigDecimalを使うのが無難です。

また、業務要件に合わせて、切り上げや切り捨てを使い分ける必要もあるでしょう。

○サンプルコード10:割合の計算と丸め処理

割合の計算でも、四捨五入が活躍します。

例えば、アンケートの集計で回答率を出す場合などです。

int totalCount = 1000;
int answerCount = 432;
double answerRate = (double)answerCount / totalCount;
double roundedRate = Math.round(answerRate * 100.0) / 100.0;
System.out.println(roundedRate); // 0.43と表示される

全体の回答数が1000件、そのうち432件の回答があったとします。

double型の answerRate を求めた後、100倍してから Math.round() で四捨五入し、再度100で割ることで小数点第2位での丸め処理を実現しています。

割合の計算結果は、パーセンテージで表示することが多いですね。

その際は、Math.round()を使った簡易的な方法でも十分でしょう。

まとめ

Javaにおける四捨五入処理、いかがでしたでしょうか。

Math.round()やBigDecimalを使った基本的な丸め方から、RoundingModeの使い分け、さらには高度な応用例まで幅広く解説してきました。

この記事が、皆さんのJavaプログラミングの助けになれば幸いです。

学んだ知識を活かして、より良いコードを書いていきましょう。

互いに高め合える環境があれば、開発の質はグンと上がるはずです。