【Java】BigDecimal完全ガイド|比較・計算・変換・四捨五入を徹底解説

当ページのリンクには広告が含まれています。
目次

BigDecimalとは?

BigDecimalの概要と必要性

BigDecimal は、Javaで高精度の小数計算を行うためのクラスです。doublefloat を使うと、2進数の丸め誤差により10進数の計算結果が正確に出ないことがあります。

特に、お金の計算や精密な計測値の計算では誤差が許されないため、BigDecimal を使用するのが一般的です

doubleやfloatとの違い

項目float / doubleBigDecimal
精度有限桁(誤差が発生する)任意の精度を保持できる
計算の誤差発生する(2進数の丸め誤差)発生しない(10進数の精度維持)
速度高速遅い(計算コストが高い)
主な用途科学計算、ゲーム、画像処理金融計算、精密計算

BigDecimalの初期化と基本操作

BigDecimal の生成方法(初期化)

String、double、int からの生成する方法です。

valueOfメソッドの引数にはlongとdoubleのものしかないのですが、intはlongのメソッドとして扱われるので問題ありません。

null の扱いと注意点

BigDecimal の変数に null が入っていると NullPointerException が発生するため適切な初期値を設定することが推奨されます。

NullPointerExceptionが発生する

何らかの初期値を入れて回避する

BigDecimalの計算

基本的な四則演算(足し算・引き算・掛け算・割り算)

計算時の優先順位

通常の数学と同じ優先順位で演算は行われません。なので計算順序には注意してください。

例えば以下のように、加算してから乗算すると加算が先に行われます。

剰余(余り)の計算

余りの算出は remainder メソッドを使います。

除算と余りの結果を両方とも取得したい場合は、divideAndRemainderメソッドを使います。その場合、戻り値はBigDecimalの配列になることに注意してください。

BigDecimalの比較方法

compareTo メソッド

比較は基本的にcompareTo メソッドを使います

戻り値のint値で比較結果を判定します。

  • 0:同値 (x == y)
  • -1:左辺が小さい (x < y)
  • 1:左辺が大きい (x > y)

equals メソッドを使わない理由

equals はスケール(小数点以下の桁数)が異なると false を返すため、値を比較する場合は compareTo を使うのが一般的です。

比較演算子 (==, >, < など) が使えない理由

BigDecimal はオブジェクトなので、== を使うと参照比較になってしまい、期待通りの動作をしません。compareTo を使用することが推奨されます。

また>, <はそもそも使えません。

BigDecimalの丸め処理(四捨五入)

setScale を使った丸め方

setScaleメソッドを使うことで小数点の桁数を指定できます。

通常は小数点の桁数を増やすために使いますが、切り捨てる桁全てが0である場合に限り桁数を減らすこともできます。

桁数を減らすことができる場合

桁数を減らせない場合はRoundingModeを指定する

もしRoundingModeを指定せずに切り捨てる桁に0以外が含まれていた場合、ArithmeticExceptionがthrowされます。

RoundingMode の種類と選び方

通常使うのは以下の3つくらいです。

  • RoundingMode.HALF_UP: 四捨五入
  • RoundingMode.DOWN: 切り捨て
  • RoundingMode.UP: 切り上げ

他のモードはこちらで確認できます。

BigDecimalの便利メソッド

小数点以下の桁数を取得

scaleメソッドを使います。

最大値・最小値を比較して取得

max, min メソッドを使います。

絶対値を取得

absメソッドを使います。

計算時の注意点

String、int、longからであれば正確に制度を維持できますが、doubleとfloatには注意が必要です。

問題があるケース

  • Stringでは問題無い桁数でも、doubleだと値が変ってしまうので、BigDecimalに格納する時点でおかしくなります。
  • floatも誤差が発生してしまいます。

対処法

  • BigDecimalに格納する前にdoubleを使わない。また、BigDecimalからdoubleに格納するのは極力避ける。
  • doubleをBigDecimalにどうしても格納する必要がある場合、しかるべき丸め仕様を決めて行う。

まとめ

  • BigDecimal は、高精度な計算が必要な場合に不可欠なクラスです。特に、金融計算など誤差が許されない場面では doublefloat ではなく BigDecimal を使用することが推奨されます。
  • BigDecimaldouble の変換には精度誤差が発生する可能性があるので、変換が必要な場合の取り扱いには注意すること。

最後までお読み頂き、ありがとうございました!
ご意見・ご要望がありましたら、遠慮なくコメント下さい!

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

リーマンショックの影響で26歳の時にIT業界から離れ、紆余曲折を経て34歳でエンジニアに復帰。
現在はフリーランスエンジニア兼コアファクトリ合同会社代表。
得意な言語はJava。

新人教育経験あり(わからなくて進まない子を放置しない方針)
Javaの新人教育にお困りでしたらお声がけください。

■保有資格
・Java Gold SE 11

コメント

コメントする

CAPTCHA


目次