자바 금액 계산으로 배운 것

6315 단어 java8자바BigDecimal

전치



프로젝트에서 사용하는 것은 Java8입니다.

일의 발단



Java에서 금액 계산이 얽힌 코딩을하고 있으며, 화면에 표시되는 값이

299.999999999999988897769753748434595763683319091796875000

처럼 미묘하게 어긋나는 사건을 만났습니다.
부끄러워하면서 제대로 (?) 금액을 계산하는 로직을 처음 썼기 때문에,
왜 그렇게 되는지 등의 이유도 조사하면서 진행했습니다.

범인 찾기



금액에 대해 백분율을 곱하는 처리의 전단에서
// どこかのmodelから取得したパーセンテージと金額
double d = 0.3;
BigDecimal bd = new BigDecimal("1000");
// 計算
BigDecimal bd2 = bd.multiply(new BigDecimal(d));
System.out.println(bd2); // 299.999999999999988897769753748434595763683319091796875000

double의 인수를 생성자에게 건네주어 BigDecimal 인스턴스를 생성하고 있었군요.
DB에서 어쩌면 얻은 결과, 여러가지로 Serverive 클래스에서 사용하고 있는 model의 필드가 double형으로 정의되고 있었습니다.

왜 어긋나?



코드상은 10진수로 정의하고 있습니다만, 내부에서는 2진수로 취급하고 있으므로,
2진수로 순환 소수가 되는 값(예를 들어 double의 0.3)은 계산을 하면 라운딩이 발생, 즉 오차가 발생합니다.


by 참조

이런 것도 안돼


double d = 3.3 / 1.1 // 3になってほしいけど2.9999999999999996

여기서 BigDecimal 님의 사용법을 재확인 (땀)



우선 참조를 읽어 보았습니다.
htps : // / cs. 오 c. 이 m/쟈ゔぁ세/jp/8/도 cs/아피/쟈ゔぁ/마 th/비 g로 시마 l. HTML

 - add
 - subtract
 - multiply
 - divide
등의 메소드를 이용해 사칙 연산합니다.
RoundingMode에서 반올림/자르기/올림 지정을 합니다.
이번 로직은 거기까지 복잡하지 않았기 때문에 까다로운 메소드는 사용하지 않았습니다.

안돼고 좋다.


// 毎回インスタンス生成、効率が悪い
BigDecimal b1 = new BigDecimal(10); //だめ
// キャッシュを使うvalueOf()
BigDecimal b2 = BigDecimal.valueOf(10); // 良い

// ∵2進数で循環小数になるものは誤差が発生する
BigDecimal b3 = new BigDecimal(0.3); // だめ
// 文字列から生成する
BigDecimal b4 = new BigDecimal("0.3"); // 良い
// doubleの値をBigDecimalに変換したいとき
BigDecimal b5 = BigDecimal.valueOf(0.3); // (なるべくならこの変換が発生する実装にはしたくないけど)
  • BigDecimal#ROUND_xxxx계는 Java9 이후로 Deprecated입니다. RoundingMode를 사용합시다 (지금의 프로젝트에서는 Java8을 사용하고 있습니다만, 버전 업을 바라보고 그 근처도 의식하고 싶습니다).

  • 참고 URL



    ㅜㅜㅜㅜㅜ 이 m / r 치 c ぇ s / 비 g로 시마 루 우사게. HTML # _ 로릉 g도
    htps : // m/TKR/ms/52635175654b9b818b89

    2019/11/12 자신의 메모



    대소 비교 (compareTo ())가 매번 모르는 경우


    BigDecimal three = BigDecimal.valueOf(3);
    BigDecimal five = BigDecimal.valueOf(5);
    
    int hoge  = three.compareTo(five); // -1 
    int piyo = three.compareTo(three); // 0
    int fuga = five.compareTo(three); // 1
    
    

    좋은 웹페이지 즐겨찾기