프로그래밍/JAVA

[JAVA] BigInteger , BigDecimal 클래스

리신 2022. 12. 14. 01:11
반응형

정수형으로 표현할 수 있는 값의 한계가 있다.

가장 큰 정수형인 long 타입도 표현 할 수 있는 값이 10진수로 19자리이다.

이 것 보다 더 큰 값을 다뤄야할 때, BigInteger를 사용한다.

 

BigInteger 

BigInteger 클래스는 내부적으로 int 배열을 사용해서 값을 다루기 때문에  long 타입보다 더 큰 값을 다룰 수 있다,

BigInteger String 처럼 immutable 이다그리고 모든 정수형이 그렇듯이 BigInteger 역시 값을 2의 보수의 형태로 표현한다.

 

BigInteger 의 생성

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

정수형 리터럴로는 표현할 수 있는 값의 한계가 있기 때문이다.

BigInteger val;
val = new BigInteger("12345678901234567890"); // 문자열로 생성
val = new BigInteger("FFFF", 16); // 16진수 값으로 입력받아서 인스턴스 생성
val = BigInteger.valueOf(123456789L); //숫자로 생성

다른 타입으로의 변환

문자열 or byte 배열

- String  toString()
- String  toString(int radix)
- byte[]   toByteArray()

 

Number로부터 상속받은 기본형

- int           intValue()
- long        longValue()
- float        floatValue()
- doueble  doubleValue()

 

메서드 중에서 이름 끝에 'Exact'가 붙은 것

- byte  byteValueExact()
- int     intValueExact()
- long  longValueExact()

 

BigInteger 의 연산

연산자와 수학적인 계산을 쉽게 해주는 메서드들이 정의되어 있다.

기본적인 연산을 수행하는 메서드 몇 개만 아래에 기입하였다.

BigInteger   add(BigInteger val)                :  덧셈
BigInteger   subtract(BigInteger val)       : 뺄셈
BigInteger   multiply(BigInteger val)       : 곱셈
BigInteger  divide(BigInteger val)            : 나눗셈
BigInteger   remainder(BigInteger val)  : 나머지

 

비트 연산 메서드

BigInteger 클래스는 워낙 큰 숫자를 다루기 위한 클래스이므로, 성능을 향상시키기 위해 비트단위로 연산을 수행하는 메서드들을 많이 가지고 있다.

메서드 설명
int bitCount() 2진수로 표현했을 때, 1의 개수 반환 (음수는 0의 개수를 반환)
int bitLength() 2진수로 표현했을 때, 값을 표현하는데 필요한 bit 수
boolean testBit(int n) 우측에서 n + 1 번째 비트가 1인지에 대한 boolean 값
BigInteger setBit(int n) 우측에서 n + 1 번째 비트를 1로 변경
BigInteger clearBig(int n) 우측에서 n + 1 번째 비트를 0으로 변경
BigInteger flipBig(int n) 우측에서 n + 1 번째 비트를 전환 (1 -> 0, 0 -> 1)

 


BigDecimal  

double 타입은 표현할 수 있는 값의 범위가 넓지만 정밀도가 최대 13자리 밖에 되지 않고 실수형의 특성상 오차를 피할 수 없다. BigDecimal 은 실수형과 달리 정수를 이용해서 실수를 표현한다. 실수를 정수와 10의 제곱의 곱으로 표현한다.

 

private final BigInteger intVal; // 정수값
private final int scale; // 지수. 소수점 이하의 자리수.
private transient int precision; // 정밀도 - 정수의 자리수

예를 들어)

123.45 는 12345 * 10-2 로 표현할 수 있으며, 이 값이 BigDecimal에 저장된다면,

intVal 은 12345, scale 은 2가 된다.

그리고 precision 은 5가 되는데, 이 값은 정수 전체자리수를 의미한다.

 

BigDecimal 의 생성

BigDecimal 을 생성하는 방법은 여러가지가 있는데, 문자열로 숫자를 표현하는 것이 일반적이다.

기본형 리터럴로는 표현할 수 있는 값의 한계가 있기 때문이다. 

 

*주의할점 : double 타입의 값을 매개변수로 주는 경우 오차가 발생할 수 있다.

BigDecimal val;
val = new BigDecimal("123.45678"); // 문자열로 생성
val = new BigDecimal(123.45678);  // double타입의 리터럴로 생성
val = new BigDecimal(12345678);  // int,long타입의 리터럴로 생성
val = BigDecimal.valueOf(123.456); // 생성자 대신 valueOF(double)사용
val = BigDecimal.valueOf(123456); // 생성자 대신 valueOf(int)사용

 

다른 타입으로의 변환

- String  toPlainString()  : 어떤 경우에도 다른 기호없이 숫자로만 표현
- String  toString()  : 필요하면 지수형태로 표현할 수도 있음

 

Number로부터 상속받은 기본형

- int         intValue()
- long      longValue()
- float      floatValue()
- double  doubleValue()

 

메서드 중에서 이름 끝에 'Exact'가 붙은 것

- byte   byteValueExact()
- short  shortValueExact()
- int      intValueExact()
- long   longValueExact()
- BigInteger toBigIntegerExact()

 

BigDecimal 의 연산

BigDecimal add(BigDecimal val)               :  덧셈
BigDecimal subtract(BigDecimal val)      : 뺄셈
BigDecimal multiply(BigDecimal val)      : 곱셈
BigDecimal divide(BigDecimal val)           : 나눗셈
BigDecimal remainder(BigDecimal val)  : 나머지

 

반올림 모드

BigDecimal 으로 나눗셈 연산을 할 때, 매개변수로 반올림을 어떻게 처리할 것인가, 몇 번째 자리 (scale) 에서 반올림 할 것인가 등을 지정할 수 있다.

 

반올림 처리 방법에 대해서 사용할 때는 다음의 RoundingMode 의 상수들을 매개변수로 주어 설정할 수 있다.

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

 

BigDecimal a = new BigDecimal("1.0");
BigDecimal b = new BigDecimal("3.0");

System.out.println(a.divide(b)); // 무한 소수로 인한 ArithmeticException 발생
System.out.println(a.divide(b, RoundingMode.HALF_UP)); // 0.333

 

scale의 변경

BigDecimal의 scale을 변경하려면,  setScale() 메서드를 사용하면 된다.

BigDecimal setScale(int newScale)
BigDecimal setScale(int newScale, int rountdingMode)
BigDecimal setScale(int newScale, RountdingMode mod)

 

 

 

*참고서적

Java의 정석

반응형