Java에서 큰 수 다루기

dev-jjun·2023년 2월 17일
0

Algorithm

목록 보기
9/15

Java 자료형의 범위

종류데이터형크기(byte / bit)표현 범위
논리형boolean1 / 8true 또는 false
문자형char2 / 16'\u0000' ~ 'uFFFF' (16비트 유니코드 문자 데이터)
정수형byte1 / 8-128 ~ 127
short2 / 16-32768 ~ 32767
int4 / 32-2147483648 ~ 2147483647
long8 / 64-9223372036854775808 ~ 9223372036854775807
실수형float4 / 321.4E-45 ~ 3.4028235E38
→ 정밀도: 7자리
double8 / 644.9E-324 ~ 1.7976931348623157E308
→ 정밀도: 15자리

BigInteger

자바에서는 변수의 정수 표현 범위를 넘어가는 경우를 고려하여 java.math 패키지에서 int, long의 원시 타입 대신 사용할 수 있는 BigInteger 클래스를 제공한다. 문제가 제시될 때 보통 최악의 경우도 고려해야 하므로 무한의 정수가 들어갈 가능성이 있다면 BigInteger를 사용하는 것이 좋다.

타입범위메모리 크기 (64bit 기준)기본/참조형저장된 위치
int-2,147,483,648 ~ 2,147,483,6474 Byte기본형Stack
long-9,223,372,036,854,775,808 ~ 9,223,372,036,854,775,8078 Byte기본형Stack
BigInteger무한 (Infinity)Minimum 70 Byte참조형Heap

* 이 범위를 넘어서면 모두 0으로 표현된다.

BigInteger는 int, long, Integer, Long 과는 달리 문자열 형태로 숫자를 처리한다.

  • BigIntger는 표현하고자 하는 자리수에 비례하여 사용하는 메모리 크기가 늘어난다.
  • BigIntger의 메모리 크기는 최소 사이즈인 70 Byte에서 “7”과 같이 한 자리 수로만 사용할 때의 메모리 크기이다.
  • 내부적으로는 int[]에 값을 저장하면서 반드시 String 타입으로만 다루도록 하므로 자릿수 부족에 관한 문제를 해결할 수 있다.

→ 따라서, 해당 클래스를 사용하는 것만으로 최소 메모리를 잡아먹는 크기가 크므로 무한이 아닌지 조건을 생각해보고 사용해야 한다.

❗ 사용법

BigInteger는 클래스 이므로, 사칙연산과 비교 등의 원시 타입에서의 숫자 연산을 모두 내부 메서드의 형태로 지원한다.

선언

import java.math.BigInteger;

BigInteger bigNum = new BigInteger("1000");

사칙연산

add(bigNum)덧셈(+)
subract(bigNum)뺄셈(-)
multiply(bigNum)곱셈(*)
divide(bigNum)나눗셈(/)
remainder(bigNum)나머지(%)

*반드시 같은 BigInteger 간의 연산만 가능하다.

형 변환

intValue()BigInteger → int
longValue()BigInteger → long
floatValue()BigInteger → float
doubleValue()BigInteger → double
toString()BigInteger → String
valueOf()int → BigInteger

비트 연산

큰 숫자를 다루며 성능을 향상시키기 위해 비트단위로 연산을 수행하도록 지원한다.

bitCount()2진수로 표현했을 때, 1의 개수 반환 (음수는 0의 개수를 반환)
bitLength()2진수로 표현했을 때, 값을 표현하는데 필요한 bit 수
testBit(int n)우측에서 n + 1 번째 비트가 1인지에 대한 boolean 값
setBit(int n)우측에서 n + 1 번째 비트를 1로 변경
clearBit(int n)우측에서 n + 1 번째 비트를 0로 변경
flipBit(int n)우측에서 n + 1 번째 비트를 전환 (1 → 0, 0 → 1)

2개의 수 비교

compareTo 사용

  • 작은 수를 큰 수랑 비교 50.comoareTo(100) → -1
  • 2개의 수가 같을 때 → 0
  • 큰 수를 작은 수랑 비교 → 1

BigDecimal

BigInteger가 정수형을 확장시켜준다면, BigDecimal은 실수형을 확장시켜주는 클래스이다. 마찬가지로 자릿수 부족이나 연산에서의 부정확성 문제를 해결해준다.

타입범위메모리 크기 (64bit 기준)기본/참조형저장된 위치
float1.4E-45 ~ 3.4028235E384 Byte기본형Stack
double4.9E~324 ~ 1.7976931348623157E3088 Byte기본형Stack
BigDecimal무한 (Infinity)Minimum 70 Byte참조형Heap

BigDecimal는 float, double 과는 달리 문자열 형태로 실수를 처리한다.

  • 내부적으로 배열을 사용하여 수치데이터를 분리해서 저장하므로 자릿수의 제한이 없다. *정수: int[ ], 실수 : char[ ]
  • 실수 연산에서는 유효 자릿수에 대한 표현 문제로 연산 결과가 의도와 다를 수 있다. → 실수끼리의 연산은 BigDecimal 클래스를 사용하는 것이 안전하다.

사칙연산

add(bigNum)덧셈(+)
subract(bigNum)뺄셈(-)
multiply(bigNum)곱셈(*)
divide(bigNum)나눗셈(/)
remainder(bigNum)나머지(%)

*나눗셈 연산 시, 매개변수로 반올림을 어떻게 처리할 것인지, 몇 번째 자리에서 반올림을 할 것인지 등을 지정할 수 있다.

BigDecimal bigNum = new BigDecimal("1.0");
BigDecimal divBigNum = new BigDecimal("3.0");
bigNum.divide(divBigNum, RoundMode.HALF_UP);

RoundingMode의 상수들을 매개변수로 전달하여 설정가능

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

형 변환

intValue()BigDecimal → int
longValue()BigDecimal → long
floatValue()BigDecimal → float
doubleValue()BigDecimal → double
toString()BigDecimal → String
toPlainString()다른 기호 없이 숫자로만 표현하여 String으로 변환
valueOf()int → BigDecimal
setScale()BigDecimal의 scale 변경

값 추출

byteValueExact()BigDecimal에서 byte값 추출
shortValueExact()BigDecimal에서 short값 추출
intValueExact()BigDecimal에서 int값 추출
longValueExact()BigDecimal에서 long값 추출
toBigIntegerExact()BigDecimal에서 BigInteger값 추출

참고 자료

[JAVA] BigInteger , BigDecimal 클래스

[java] 자바_ BigInteger & BigDecimal 클래스 원리 쉽게 정리/범위/기본 int형/반복문/사칙연산 메소드

profile
서버 개발자를 꿈꾸며 성장하는 쭌입니다 😽

0개의 댓글