fun main() {
val n1 = 90.15f
val n2 = 30.05f
println(n1 / n2)
}
Java와 Kotlin으로 개발하는 개발자들은
소숫점을 다룰 때 골칫덩어리인 부분이 하나 있습니다.
바로 부동소숫점 오류로 인해 소숫점이 제대로 표현되지 않을 때지요.
double은 float형에 비해 조금 덜하나, 부동소숫점 오류에서 완전히 자유롭진 못합니다.
또, 매우 큰 수를 다룰 때에도 자료형의 최대 / 최소 값을 넘어버리는 경우도 있습니다.
이럴때 필요한게 바로 BigDecimal 입니다.
BigDecimal 이란?
Decimal은 흔히 십진법, 혹은 소수라는 의미를 가지고 있습니다.
앞에 Big이 붙은 것에서 알 수 있듯이
자바 혹은 코틀린에서 큰 수를 다룰 때, 혹은 소숫점을 다룰 때 사용하는 클래스로써,
돈과 같이 오류가 나서는 안되는 작업을 하고 있을때는 선택이 아닌 필수입니다.
BigDecimal의 생성
import java.math.BigDecimal
BigDecimal은 java.math안에 정의되어 있습니다.
java의 클래스인 만큼, 코틀린 말고도 자바에서도 사용이 가능합니다.
val n1 = BigDecimal("90.15")
val n2 = BigDecimal.valueOf(90.15)
BigDecimal은 위와 같이 숫자를 문자열 형태로 넘겨 생성하거나,
valueOf안에 숫자를 넣어 생성할 수 있습니다
주의할 점은, BigDecimal(90.15)와 같이 문자열이 아닌 숫자열을 그냥 넣을 시
부동 소숫점 오류가 BigDecimal에서도 그대로 나타나게 됩니다.
BigDecimal로 사칙연산
fun main() {
val n1 = BigDecimal("90.15")
val n2 = BigDecimal("30.05")
// 덧셈
println(n1.add(n2))
println(n1 + n2)
// 뺄셈
println(n1.subtract(n2))
println(n1 - n2)
// 곱셈
println(n1.multiply(n2))
println(n1 * n2)
// 나눗셈
println(n1.divide(n2))
println(n1 / n2)
}
자바로 BigDecimal을 다룰 때에는
n1.add(n2),
n1.substract(n2)와 같이 사용하여야 했습니다.
그러나 코틀린에서는 +, -, *, / 를 사용한 BigDecimal 연산을 지원하기 때문에
int나 double같이 기존 실수형 자료형에서 연산하듯이 간편하게 사용할 수 있습니다.
BigDecimal 비교
val n1 = BigDecimal("90.15")
val n2 = BigDecimal("30.05")
n1.compareTo(n2)
BigDecimal에서 비교는 n1.compareTo(n2)와 같이 비교할 수 있습니다.
n1이 더 크다면 1, 같다면 0, 작다면 -1을 반환합니다.
fun main() {
val n1 = BigDecimal("90.15")
val n2 = BigDecimal("30.05")
val n3 = BigDecimal("90.15")
if(n1 == n2) {
println("n1과 n2는 같다")
} else {
println("n1과 n2는 같지 않다")
}
if(n1 == n3) {
println("n1과 n3는 같다")
} else {
println("n1과 n3는 같지 않다")
}
}
코틀린에서는 ==, >, >=, <, <= 연산 역시 지원하기 때문에
위와 같이 사용할 수도 있습니다.
* 자바에서 BigDecimal을 ==로 비교 시, String을 ==로 비교하는 것 처럼,
주소값을 비교하기 때문에 의도와 다른 결과를 낼 수 있습니다
후기
float와 double 타입으로 소숫점 연산을 하다가
부동소숫점 오류로 인해 수많은 고통을 받은 끝에,
BigDecimal이라는 유용한 클래스를 알았던 순간은 아직도 잊을 수가 없습니다.
BigDecimal은 은행과 같이 돈과 관련된 연산이라면 거의 무조건적으로 사용한다고 하더군요.
매우 큰 수를 다뤄야 하거나, 소숫점을 다뤄야 할 때에도 마찬가지 입니다.
아무래도 int, double, float, long과 같은 자료형 보다는 느릴 수 밖에 없으나,
BigDecimal의 정밀도와 신뢰성은 위의 단점을 충분히 상쇄시키고도 남습니다.
BigDecimal을 처음 알았을 때는 자바를 주로 쓰고 있을 때 였는데,
자바로 n1.add(n2), n1.divide(n2)와 같이 쓰다가 +,-,/,*, == 등으로
기존 실수형을 쓰듯이 연산하니 정말 너무 편하네요.
'언어 > Kotlin' 카테고리의 다른 글
코틀린의 반올림 방식 : 오사오입 (0) | 2023.06.14 |
---|---|
[Kotlin/코틀린] 여러 조건을 기준으로 정렬하기 (0) | 2023.05.21 |
자바의 StringBuilder 개행문자 삽입방법 - append(str + "\n") vs append(str).append("\n") (0) | 2023.02.01 |
[Kotlin] Jsoup와 크롤링으로 백준 푼 문제 중 포스팅하지 않은 문제 추려내기 (0) | 2022.11.23 |
[Kotlin] 배열 사용법 정리 (1) | 2022.02.16 |