[기본 개념] 4 | (2.4) Java.math.BigInteger 클래스, Java.math.BigDecimal 클래스

728x90

[기본 개념] 4 | (2.4) Java.math.BigInteger 클래스, Java.math.BigDecimal 클래스

1 java.util.Objects클래스

2 java.util.Random클래스

3 정규식(Regular Expression) - java.util.regex패키지

4 java.util.Scanner클래스

5 java.util.StringTokenizer클래스

6> java.math.BigInteger클래스

7> java.math.BigDecimal클래스

6. java.math.BigInteger클래스

정수형으로 표현할 수 있는 값보다 더 큰 값을 다뤄야 할 때 BigInteger클래스를 사용하면 좋다.

 

 BigInteger클래스는 내부적으로 int배열을 사용해서 값을 다루기 때문에 훨씬 큰 값을 다룰 수 있으며 String처럼 불변(immutable)이다.

 

 그리고 부호를 따로 저장하고 배열에는 값을 저장한다. 그래서 signum(부호)의 값은 1(양수), 0, -1(음수) 셋 중에 하나이고 부호만 다른 두 숫자에서 mag(값)은 같다.

 

BigInteger의 생성

보통 문자열로 숫자를 표현하는 것이 일반적이다.

 

BigInteger val ;

val = new BigInteger("12345678901234567890") ;   // 문자열로 생성

val = new BigInteger("FFFF", 16) ;                                      // n진수(radix)의 문자열로 생성

val = BigInteger.valueOf(1234567890L) ;                       // 숫자로 생성

 

다른 타입으로의 전환

BigInteger를 문자열, 또는 byte배열로 변환하는 메서드는 다음과 같다.

 

String toString( )                         // 문자열로 변환

String toString(int radix)        // 지정된 진법(radix)의 문자열로 변환

byte[ ] toByteArray( )               // byte배열로 변환

 

BigInteger도 Number로부터 상속받은 기본형으로 변환하는 메서드를 가지고 있다.

 

int intValue( )

long longValue( )

float floatValue( )

double doubleValue( )

 

 정수형으로 변환하는 메서드 중에 이름 끝에 'Exact'가 붙은 것들은 변환한 타입의 범위에 속하지 않으면 ArithmeticException을 발생시킨다.

 

BigInteger의 연산

정수형에 사용할 수 있는 모든 연산자와 계산을 쉽게 해주는 메서드들이 정의돼 있다.

 

BigInteger add(BigInteger val)                  // 덧셈 (this + val)

BigInteger subtract(BigInteger val)        // 뺄셈 (this - val)

BigInteger multiply(BigInteger val)        // 곱셈 (this * val)

BigInteger divide(BigInteger val)             // 나눗셈 (this / val)

BigInteger remainder(BigInteger val)     // 나머지 (this % val)

 

비트 연산 메서드

 큰 숫자를 다루기 위한 클래스이므로 성능을 향상시키기 위해 비트단위로 연산을 수행하는 메서드들을 많이 가지고 있다. and, or, xor, not가 같은 메서드와 다음과 같은 메서드들도 제공한다.

 

int bitCount( )                                // 2진수로 표현했을 때, 1의 개수(음수는 0의 개수)를 반환

int bitLength( )                              // 2진수로 표현했을 때, 값을 표현하는데 필요한 bit수

boolean testBit(int n)                // 우측에서 n+1번째 비트가 1이면 true, 0이면 false

BigInteger setBit(int n)             // 우측에서 n+1번째 비트를 1로 변경

BigInteger clearBit(int n)         // 우측에서 n+1번째 비트를 0으로 변경 

BigInteger flipBit(int n)             // 우측에서 n+1번째 비트를 전환 (1 -> , 0 -> 1) 

7. java.math.BigDecimal클래스

 double타입은 정밀도가 최대 13자리밖에 되지 않고 실수형의 특성상 오차를 피할 수 없다. BigDecimal은 정수를 이용하여 실수를 정수와 10의 제곱의 곱으로 표현하며 String처럼 불변이다.

 

 지수인 scale은 0부터 Integer.MAX_VALUE사이의 범위에 있는 값이다. 그리고 정수를 저장하는데 BigInteger를 사용한다.

 

private final BigInteger intVal ;             // 정수(unscaled value)

private final int scale ;                               // 지수(scale)

private transient int precision ;            // 정밀도(precision) - 정수의 자릿수

 

BigDecimal의 생성

보통 문자열로 숫자를 표현한다.

 

BigDecimal val ;

val = new BigDecimal("123.4567890") ;       // 문자열로 생성

val = new BigDecimal(123.456) ;                     // double타입의 리터럴로 생성

val = new BigDecimal(123456) ;                      // int, long타입의 리터럴로 생성

val = BigDecimal.valueOf(123.456) ;             // 생성자 대신 valueOf(double) 사용

val = BigDecimal.valueOf(123456) ;               // 생성자 대신 valueOf(int) 사용

 

한 가지 주의할 점은 double타입의 값을 매개변수로 갖는 생성자를 사용하면 오차가 발생할 수 있다.

 

다른 타입으로의 변환

BigDecimal을 문자열로 변환하는 메서드는 다음과 같다.

 

String toPlainString( )           // 어떤 경우에도 다른 기호 없이 숫자로만 표현

String toString( )                         // 필요하면 지수 형태로 표현할 수 있음

 

 BigDecimal도 BigInteger처럼 Number로부터 상속받은 기본형으로 변환하는 메서드들을 가지고 있으며 정수형으로 변환하는 메서드 중에서 이름 끝에 'Exact'가 붙은 것들은 변환한 타입의 범위에 속하지 않으면 ArithmeticException을 발생시킨다.

 

BigDecimal의 연산

실수형에 사용할 수 있는 모든 연산자와 계산을 쉽게 해주는 메서드들이 정의돼 있다.

 

BigDecimal add(BigDecimalr val)                  // 덧셈 (this + val)

BigDecimal subtract(BigDecimal val)        // 뺄셈 (this - val)

BigDecimal multiply(BigDecimal val)        // 곱셈 (this * val)

BigDecimal divide(BigDecimal val)             // 나눗셈 (this / val)

BigDecimal remainder(BigDecimal val)     // 나머지 (this % val)

 

그리고 주의할 점은 연산을 하면 정수, 지수, 정밀도가 달라진다.

 

반올림 모드 - divide( )와 setScale( )

 나눗셈을 처리하기 위한 메서드가 다양하게 존재하는데 결과를 어떻게 반올림(roundingMode)처리할 것인지, 몇 번째 자리(scale)에서 반올림할 것인지 지정할 수 있다.

 

반올림 처리방법은 가능한 밑에 나와있는 열거형 RoundingMode를 사용하는 것이 좋다.

 

상수 설명
CEILING 올림
FLOOR 내림
UP 양수일 때는 올림, 음수일 때는 내림
DOWN 양수일 때는 내림, 음수일 때는 올림
HALF_UP 반올림(5이상 올림, 5미만 버림)
HALF_EVEN 반올림(반올림 자리의 값이 짝수면 HALF_DOWN, 홀수면 HALF_UP)
HALF_DOWN 반올림(6이상 올림, 6미만 버림)
UNNECESSARY 나눗셈의 결과가 딱 떨어지는 수가 아니면, ArithmeticException발생

 

 주의해야 할 점은 divide( )로 나눗셈한 결과가 무한소수일 경우 반올림 모드를 지정해주지 않으면 ArithmeticException이 발생한다.

 

java.math.MathContext

 반올림 모드와 정밀도(precision)을 하나로 묶어 놓은 클래스이다. 이 클래스에서는 precision이 정수와 소수점 이하를 모두 포함한 자리수를 의미한다.

 

scale의 변경

BigDecimal의 scale을 변경하려면, setScale( )을 이용하면 된다.

 

setScale( )로 scale의 값을 줄이는 것10의 n제곱으로 나누는 것과 같으므로 오차가 발생할 수 있고 반올림 모드를 지정해주어야 한다.

 

 

 

 

출처 | Java의 정석 (남궁 성)

728x90