エンジニアの将来って?

現在7年目のCOBOL→Java→C#エンジニアが、将来への考えや勉強のアウトプット、たまに腎臓について書くブログです

【Java】BigDecimal型とdouble型と比較

こんにちは。たいら(@tairaengineer2)です。
この記事でJavaBigDecimal型double型の比較を解説した記事です。

 

前提条件:eclipseの環境

この記事では、eclipseのバージョンは

バージョン Eclipse4.7 Oxygen

を使っています。
インストールの仕方は、下の記事をご参考ください。

www.tairax.com

BigDecimal型とdouble型の違い

BigDecimal型とdouble型の違いを

  • 変数宣言について
  • 計算について
  • 計算誤差について

でまとめました。

変数宣言について
特徴
BigDecimal型 宣言するのが少し手間 BigDecimal bigDecimalCal2 = BigDecimal.valueOf(0.9);
double型 宣言が楽 double doubleCal2 = 0.9;
計算について
特徴
BigDecimal型 メソッドを使う必要がある BigDecimal result = big1.add(big2);
double型 double sample = 0.1 + 1.28;
計算誤差について
特徴
BigDecimal型 誤差が発生しない
double型 誤差が発生する

誤差について、もっと解説します。
実際にどういうときに誤差が生じるのかを見ていきましょう。

double型とBigDecimal型で誤差を生じさせる

double型とBigDecimal型で同じ計算をして比較します。
どちらも1と0.9に対して、

  • 足し算
  • 引き算
  • 掛け算
  • 割り算

上記、4種類の計算をします。

BigDecimalについては、以下の記事を参照ください。

www.tairax.com

Javaサンプルコード

package bigDecimalSample;

import java.math.BigDecimal;
import java.math.RoundingMode;

/**
 * double型とBigDecimal型の違いを確認するクラス
 *
 */
public class BigDecimalSample {
    public static void main(String[] args) {
        // double型の変数を生成
        double doubleCal1 = 1;
        double doubleCal2 = 0.9;

        // BigDecimal型の変数を生成
        BigDecimal bigDecimalCal1 = BigDecimal.ONE;
        BigDecimal bigDecimalCal2 = BigDecimal.valueOf(0.9);

        // double型とBigDecimal型の計算結果の違いを確認
        double doubleAdd = doubleCal1 + doubleCal2;
        double doubleSub = doubleCal1 - doubleCal2;
        double doubleMul = doubleCal1 * doubleCal2;
        double doubleDev = doubleCal1 / doubleCal2;

        BigDecimal bigDecimalAdd = bigDecimalCal1.add(bigDecimalCal2);
        BigDecimal bigDecimalSub = bigDecimalCal1.subtract(bigDecimalCal2);
        BigDecimal bigDecimalMul = bigDecimalCal1.multiply(bigDecimalCal2);
        BigDecimal bigDecimalDev = bigDecimalCal1.divide(bigDecimalCal2, 3, RoundingMode.HALF_UP);

        System.out.println("----------足し算----------");
        System.out.println("double型  :" + doubleAdd);
        System.out.println("BigDecimal型:" + bigDecimalAdd);

        System.out.println("----------引き算----------");
        System.out.println("double型  :" + doubleSub);
        System.out.println("BigDecimal型:" + bigDecimalSub);

        System.out.println("----------掛け算----------");
        System.out.println("double型  :" + doubleMul);
        System.out.println("BigDecimal型:" + bigDecimalMul);

        System.out.println("----------割り算----------");
        System.out.println("double型  :" + doubleDev);
        System.out.println("BigDecimal型:" + bigDecimalDev);

    }
}

実行結果

----------足し算----------
double型  :1.9
BigDecimal型:1.9
----------引き算---------- 
double型  :0.09999999999999998
BigDecimal型:0.1
----------掛け算----------
double型  :0.9
BigDecimal型:0.9
----------割り算----------
double型  :1.1111111111111112
BigDecimal型:1.111

どうでしょう。足し算と掛け算に差異はありませんでした。
しかし、引き算と割り算には差異があります。
特に引き算。なんで0.1にならなかったんだ… という方はこれをご参考に

qiita.com

このように同じ計算でも場合によっては結果が異なることを誤差と言います。
誤差が生まれるケースとしては、割り算で答えが無限小数になる場合などです。
この誤差が許されないときに、BigDecimalはよく使われます。

まとめ:double型とBigDecimal型を使い分けよう

以上が、double型とBigDecimal型の比較です。
使い分けとして

  • BigDecimal型:金額計算など、誤差が絶対許されないときに使う
  • double型:上記以外の場合に使う

少しでも、あなたの参考になれば幸いです。
ではでは~(・ω・)ノシ

 

ほかにも勉強記事を書いてます。
よければご参考ください。

今までブログで書いたJavaの文法解説記事のまとめ

【Java8】mapToObjメソッドを使ってFizzBuzz問題【ラムダ式】

【Java】TreeSetの特徴を分かりやすく解説します。