카테고리 없음
[JAVA] 부동 소수점 오차, BigDecimal
wooyeon06
2024. 4. 1. 15:10
1. 부동 소수점 방식 오차
부동 소수점 방식은 고정 소수점 방식보다 훨씬 더 많은 범위까지 표현할 수 있지만, 항상 오차가 존재한다는 단점을 가지고 있다.
부동 소수점 방식에서 오차는 위에서 살펴본 공식에 의해 발생한다.
해당 공식을 사용하면 표현할 수 있는 범위는 늘지만, 10진수를 정확하게 표현할 수는 없다. (무한소수, 순환소수의 경우 가수부가 표현할 수 있는 비트 수를 넘어가게 되면 손실되는 부분이 생기기 때문, 실수 또한 이진수로 표현하기 때문에 가수부가 1/2^n 꼴로 표현되는 경우만 오차없이 정확하게 값이 계산된다.)
float형 타입이 소수 6자리까지는 정확하게 표현할 수 있으나, 그 이상은 정확하게 표현하지 못함을 보여준다.
자바의 double형 타입은 소수부분 15자리까지 오차없이 표현할 수 있다. 하지만 그 이상의 소수 부분을 표현할 때는 언제나 작은 오차가 발생하게 된다.
> BigDecimal사용, 정수형계산( d = (d*10+ 0.1d*10) / 10; )
2. BigDecimal
- 정밀한 연산: BigDecimal은 정밀한 십진수 연산을 지원하여 부동 소수점 연산의 부정확성을 회피할 수 있습니다.
(부동 소수점 연산에 안전하게 사용하려면 부동 소수점을 문자열로 변환) - 고정 소수점 연산: 부동 소수점 연산과 달리 고정 소수점 연산을 수행하며, 정확한 숫자를 표현할 수 있습니다.
- 불변 클래스: BigDecimal 객체는 한 번 생성되면 수정할 수 없는 불변 객체입니다. 따라서 새로운 연산을 수행할 때마다 새로운 BigDecimal 객체가 생성됩니다.
BigDecimal number1 = new BigDecimal("123.45");
BigDecimal number2 = BigDecimal.valueOf(67.89);
BigDecimal result = number1.add(number2); // 덧셈
BigDecimal result = number1.subtract(number2); // 뺄셈
BigDecimal result = number1.multiply(number2); // 곱셈
BigDecimal result = number1.divide(number2); // 나눗셈
// 소수점 이하 10자리까지 반올림
BigDecimal result = number1.divide(number2, 10, RoundingMode.HALF_UP);
// number1과 number2 비교
//(-1: number1 < number2, 0: number1 == number2, 1: number1 > number2)
int cmp = number1.compareTo(number2);
String numberString = number1.toString();
https://velog.io/@syleemk/CS-%EB%B6%80%EB%8F%99-%EC%86%8C%EC%88%98%EC%A0%90-%EC%98%A4%EC%B0%A8