자바 금액 계산으로 배운 것
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); // (なるべくならこの変換が発生する実装にはしたくないけど)
double d = 3.3 / 1.1 // 3になってほしいけど2.9999999999999996
// 毎回インスタンス生成、効率が悪い
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); // (なるべくならこの変換が発生する実装にはしたくないけど)
참고 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
Reference
이 문제에 관하여(자바 금액 계산으로 배운 것), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/nobi_tum/items/e2db023c55f04d3edeb4텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)