double타입으로 표현할 수 있는 값은 범위가 넓으나
정밀도가 최대 13자리밖에 되지않아 오차를 피할 수 없다.
https://standout.tistory.com/22
https://standout.tistory.com/56
java.math.BigDecimal는 오차가없는 2진수로 변환하여 다룬다.
BigDecimal 는 문자열, double, int, long으로 생성가능하고
valueOf로 생성자대신 생성도 가능하다.
import java.math.BigDecimal;
public class BigDecimalCreationExample {
public static void main(String[] args) {
// 문자열로 BigDecimal 생성
BigDecimal fromString = new BigDecimal("123456.789");
System.out.println("From String: " + fromString);
//From String: 123456.789
// double로 BigDecimal 생성
double fromDouble = 9876.54321;
BigDecimal fromDoubleValue = new BigDecimal(fromDouble);
System.out.println("From Double: " + fromDoubleValue);
//From Double: 9876.54321
// int로 BigDecimal 생성
int fromInt = 42;
BigDecimal fromIntValue = new BigDecimal(fromInt);
System.out.println("From Int: " + fromIntValue);
//From Int: 42
// long으로 BigDecimal 생성
long fromLong = 123456789012345678L;
BigDecimal fromLongValue = new BigDecimal(fromLong);
System.out.println("From Long: " + fromLongValue);
//From Long: 123456789012345678
// valueOf 메서드로 BigDecimal 생성
BigDecimal valueOfExample = BigDecimal.valueOf(98765.4321);
System.out.println("Using valueOf: " + valueOfExample);
//Using valueOf: 98765.4321
}
}
BigDecimal 는 이 실수의 각 구성 부분 혹은 자릿수를 반환하는 메서드를 제공한다.
unscaledValue()
scale()
precision()
import java.math.BigDecimal;
import java.math.BigInteger;
public class BigDecimalMethodsExample {
public static void main(String[] args) {
// BigDecimal 객체 생성
BigDecimal bigDecimalValue = new BigDecimal("12345678901234567890.12345");
// unscaledValue() 메서드: BigDecimal의 정수 부분을 BigInteger로 반환
BigInteger unscaledValue = bigDecimalValue.unscaledValue();
System.out.println("Unscaled Value: " + unscaledValue);
//Unscaled Value: 12345678901234567890123450
// scale() 메서드: BigDecimal의 소수 부분의 스케일(10의 거듭제곱)을 반환
int scale = bigDecimalValue.scale();
System.out.println("Scale: " + scale);
//Scale: 5
// precision() 메서드: BigDecimal의 정밀도 (전체 자릿수)를 반환
int precision = bigDecimalValue.precision();
System.out.println("Precision: " + precision);
//Precision: 26
}
}
다른타입으로 변환하는 BigDecimal메서드는 다음과 같다.
String toPlainString()
소수점이하의 불필요한 0을 제거후 문자열형태로 반환
String toString()
지수표기법이나 정규표현식에 따라 지정된 형식으로 반환
import java.math.BigDecimal;
public class BigDecimalToStringComparison {
public static void main(String[] args) {
// BigDecimal 객체 생성 (1.0e-22)
BigDecimal bigDecimalValue = new BigDecimal("1.0e-22");
// toPlainString() 메서드 사용
String plainString = bigDecimalValue.toPlainString();
System.out.println("toPlainString(): " + plainString);
// toString() 메서드 사용
String regularString = bigDecimalValue.toString(); //toPlainString(): 0.00000000000000000000001
System.out.println("toString(): " + regularString); //toString(): 1.0E-22
}
}
int intValue
long longValue()
float floatValue()
double doubleValue()
기본형으로 변환한다.
import java.math.BigDecimal;
public class BigDecimalToPrimitiveExample {
public static void main(String[] args) {
// BigDecimal 객체 생성
BigDecimal bigDecimalValue = new BigDecimal("12345.67890");
// int로 변환
int intValue = bigDecimalValue.intValue();
System.out.println("intValue(): " + intValue);
//intValue(): 12345
// long으로 변환
long longValue = bigDecimalValue.longValue();
System.out.println("longValue(): " + longValue);
//longValue(): 12345
// float으로 변환
float floatValue = bigDecimalValue.floatValue();
System.out.println("floatValue(): " + floatValue);
//floatValue(): 12345.678
// double로 변환
double doubleValue = bigDecimalValue.doubleValue();
System.out.println("doubleValue(): " + doubleValue);
//doubleValue(): 12345.6789
}
}
이 뒤에 Exact가 붙으면 결과가 타입의 범위에 속해있지않을경우 예외를 발생한다.
byte byteValueExact()
short shortValueExact()
int intValueExact()
long longValueExact()
BigInteger toBigIntegerValueExact()
import java.math.BigDecimal;
import java.math.BigInteger;
public class BigDecimalExactConversionExample {
public static void main(String[] args) {
// BigDecimal 객체 생성
BigDecimal bigDecimalValue = new BigDecimal("12345.67890");
try {
// byte로 변환
byte byteValue = bigDecimalValue.byteValueExact();
System.out.println("byteValueExact(): " + byteValue);
} catch (ArithmeticException e) {
System.out.println("byteValueExact() Exception: " + e.getMessage());
}
try {
// short로 변환
short shortValue = bigDecimalValue.shortValueExact();
System.out.println("shortValueExact(): " + shortValue);
} catch (ArithmeticException e) {
System.out.println("shortValueExact() Exception: " + e.getMessage());
}
try {
// int로 변환
int intValue = bigDecimalValue.intValueExact();
System.out.println("intValueExact(): " + intValue);
} catch (ArithmeticException e) {
System.out.println("intValueExact() Exception: " + e.getMessage());
}
try {
// long으로 변환
long longValue = bigDecimalValue.longValueExact();
System.out.println("longValueExact(): " + longValue);
} catch (ArithmeticException e) {
System.out.println("longValueExact() Exception: " + e.getMessage());
}
try {
// BigInteger로 변환
BigInteger bigIntegerValue = bigDecimalValue.toBigIntegerExact();
System.out.println("toBigIntegerExact(): " + bigIntegerValue);
} catch (ArithmeticException e) {
System.out.println("toBigIntegerExact() Exception: " + e.getMessage());
}
}
}
BigDecimal의 연산메서드는 아래와같다.
BigDecimal add( BigDecimal val)
BigDecimal substract( BigDecimal val)
BigDecimal multiply( BigDecimal val)
BigDecimal divide( BigDecimal val)
BigDecimal remainder( BigDecimal val)
import java.math.BigDecimal;
public class BigDecimalArithmeticExample {
public static void main(String[] args) {
// BigDecimal 객체 생성
BigDecimal firstValue = new BigDecimal("10.5");
BigDecimal secondValue = new BigDecimal("2.5");
// add 메서드: 덧셈
BigDecimal addResult = firstValue.add(secondValue);
System.out.println("addResult: " + addResult);
//addResult: 13.0
// subtract 메서드: 뺄셈
BigDecimal subtractResult = firstValue.subtract(secondValue);
System.out.println("subtractResult: " + subtractResult);
//subtractResult: 8.0
// multiply 메서드: 곱셈
BigDecimal multiplyResult = firstValue.multiply(secondValue);
System.out.println("multiplyResult: " + multiplyResult);
//multiplyResult: 26.25
// divide 메서드: 나눗셈
BigDecimal divideResult = firstValue.divide(secondValue, 2, BigDecimal.ROUND_HALF_UP);
System.out.println("divideResult: " + divideResult);
//divideResult: 4.20
// remainder 메서드: 나머지
BigDecimal remainderResult = firstValue.remainder(secondValue);
System.out.println("remainderResult: " + remainderResult);
//remainderResult: 0.5
}
}
BigDecimal의 반올림메서드는 아래와같으며 나눗셈의 결과를 어떻게 반올림할 것인지를 지정할 수 있다.
BigDecimal이 아무리 오차가 없더라도 나눗셈에서 발생하는 오차는 어쩔 수 없다.
반올림모드를 지정해주지않으면 ArithmeticException 예외가 발생한다.
RoundingMode는 반올림 처리방법에 대한것으로
BigDecimal에 정의된 ROUNT_로 시작하는 상수등 중 하나를 선택해 사용한다.
CELING 올림
FLOOR 내임
UP 양수일때 올림, 음수일때 내림
DOWN 양수일때 내림, 음수일때 올림
HALF_UP 5이상올림, 5미만버림
HALF_EVEN 반올림자리값이 짝수면 HALF_DOWN, 홀수면 HALF_UP
HALF_DOWN 6이상 올림, 6미만 버림
UNNECESSARY 결과가 딱떨어지지않는다면, 예외발생
divide()
// BigDecimal 객체 생성
BigDecimal numerator = new BigDecimal("10");
BigDecimal denominator = new BigDecimal("3");
// divide 메서드로 나눗셈 수행
BigDecimal result = numerator.divide(denominator, 5, BigDecimal.ROUND_HALF_UP);
System.out.println("Result with default rounding: " + result);
//Result with default rounding: 3.33333
setScale()
// setScale 메서드로 소수점 이하 자릿수와 반올림 모드 설정
BigDecimal originalValue = new BigDecimal("123.456789");
BigDecimal roundedResult = originalValue.setScale(2, RoundingMode.HALF_UP);
System.out.println("Rounded Result: " + roundedResult);
// Output: Rounded Result: 123.46
java.math.MathContext
setScale과 같이 소수점 이하의 자릿수를 조절하는 방법에 MathContext도 있다.
일반적으로 setScale는 특정 BigDecimal객체를, MathContext는 BigDecimal 연산에 대한 일괄적 설정을 위해 사용한다.
MathContext mathContext = new MathContext(2, RoundingMode.HALF_UP);
BigDecimal valueWithContext = new BigDecimal("123.456789", mathContext);
System.out.println("Value with MathContext: " + valueWithContext);
// Output: Value with MathContext: 120
'JAVA' 카테고리의 다른 글
DecimalFormat, 숫자데이터를 다양한 형식으로 표현하다 (0) | 2023.12.28 |
---|---|
Calendar와 Date, 이를 이용한 날짜/ 일수 출력하기 (0) | 2023.12.28 |
java.math.BigInteger long보다 큰 정수값을 계산할때 (0) | 2023.12.26 |
String.split()의 구식 api, java.util.StringTokenizer (0) | 2023.12.26 |
java.util.Scanner 입력소스를 읽다 (0) | 2023.12.26 |