본문 바로가기

명사 美 비격식 (무리 중에서) 아주 뛰어난[눈에 띄는] 사람[것]

JAVA

java.math.BigDecimal, double타입보다 오차가 없도록 2진수로 변환해 수를 다루다

double타입으로 표현할 수 있는 값은 범위가 넓으나

정밀도가 최대 13자리밖에 되지않아 오차를 피할 수 없다.

https://standout.tistory.com/22

 

숫자의 종류, 실수 무리수 유리수 정수 자연수

간단히 예시로 정리하자. 실수 floating point number 3.14 무리수 irrational number 𝝅 유리수 rational number ⅛ 정수 integer ... -2, -1, 0, 1, 2 … 자연수 natural number 1, 2, 3, 4, 5, 6 … 실수, floating point 3141592란 수에

standout.tistory.com

https://standout.tistory.com/56

 

자바 기본타입 (bsilfdcb)

외워보자. bsil fd cb 비실한 fd가 시비를 건다. 자바에서 값을 표현할때 데이터 타입으로 정수, 실수, 논리형을 가진다. 위 표를 봐보자, 최소단위 byte는 1byte로 8bit를 가지고 있고, 256자리를 표현, -1

standout.tistory.com

 

 

 

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