원시 유형 | 메모리 크기 | 값 범위 |
---|---|---|
바이트 | 8비트 | -128 ~ 127 |
짧은 | 16비트 | -32768 ~ 32767 |
숯 | 16비트 | 0 ~ 65536 |
정수 | 32비트 | -2147483648 ~ 2147483647 |
긴 | 64비트 | -9223372036854775808 ~ 9223372036854775807 |
뜨다 | 32비트 | (2의 -149승) ~ ((2의 -23승) * 2의 127승) |
더블 | 64비트 | (-2의 63승) ~ ((2의 63승) - 1) |
부울 | 8(배열로 사용하는 경우), 32(배열로 사용하지 않는 경우) | 참 또는 거짓 |
public class Main {
public static void main(String[] args) {
BigInteger integer = new BigInteger("11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111");
System.out.println(integer);
BigDecimal decimal = new BigDecimal("123.444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444");
System.out.println(decimal);
}
}
문자열을 생성자에 전달하는 것은 가능한 옵션 중 하나일 뿐입니다. 여기서 우리는 숫자가 long 및 double 의 최대값을 초과하기 때문에 문자열을 사용합니다. 컴파일러에게 어떤 숫자를 만들고 싶은지 설명할 방법이 필요합니다. 111111111111111111111111111111111111111111111111111111111111111111111 생성자에 대한 작업은 작동하지 않습니다. Java는 전달된 숫자를 기본 데이터 유형 중 하나로 밀어 넣으려고 시도하지만 그 중 어느 것에도 맞지 않습니다. 그렇기 때문에 문자열을 사용하여 원하는 숫자를 전달하는 것이 좋은 선택입니다. 두 클래스 모두 전달된 문자열에서 숫자 값을 자동으로 추출할 수 있습니다. 큰 숫자의 클래스로 작업할 때 기억해야 할 또 다른 중요한 점은 객체가 불변( Immutable )이라는 것입니다. 기본 유형(Integer, Long 등)에 대한 래퍼 클래스 및 String 클래스 에 대한 경험 덕분에 이미 불변성에 대해 잘 알고 있습니다 .
import java.math.BigInteger;
public class Main {
public static void main(String[] args) {
BigInteger integer = new BigInteger("11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111");
System.out.println(integer);
integer.add(BigInteger.valueOf(33333333));
System.out.println(integer);
}
}
콘솔 출력:
11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
예상하셨겠지만 저희 번호는 변경되지 않았습니다. 더하기 연산을 수행하려면 연산 결과를 받을 새 객체를 생성해야 합니다.
import java.math.BigInteger;
public class Main {
public static void main(String[] args) {
BigInteger integer = new BigInteger("11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111");
System.out.println(integer);
BigInteger result = integer.add(BigInteger.valueOf(33333333));
System.out.println(result);
}
}
콘솔 출력:
11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111144444444
보세요, 이제 모든 것이 정상적으로 작동합니다 :) 그런데, 덧셈 연산이 얼마나 특이한지 눈치채셨나요?
BigInteger result = integer.add(BigInteger.valueOf(33333333));
이것은 또 다른 중요한 포인트입니다. 큰 숫자 클래스는 + - * / 연산자를 사용하지 않습니다. 대신 일련의 메서드를 제공합니다. 주요 방법에 대해 알아보겠습니다(항상 그렇듯이 Oracle 설명서( 여기 및 여기 )에서 전체 방법 목록을 찾을 수 있습니다 ).
-
산술 연산을 위한 메서드: add() , 뺄셈() , multiply() , divide() . 이러한 방법은 각각 덧셈, 뺄셈, 곱셈 및 나눗셈을 수행하는 데 사용됩니다.
-
doubleValue() , intValue() , floatValue() , longValue() 등은 큰 숫자를 Java의 기본 유형 중 하나로 변환하는 데 사용됩니다. 이러한 방법을 사용할 때는 주의하십시오. 비트 크기의 차이를 잊지 마세요!
import java.math.BigInteger; public class Main { public static void main(String[] args) { BigInteger integer = new BigInteger("11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111"); long result = integer.longValue(); System.out.println(result); } }
콘솔 출력:
8198552921648689607
-
min() 및 max()를 사용 하면 두 개의 큰 숫자의 최소값과 최대값을 찾을 수 있습니다.
이러한 메서드는 정적이 아닙니다!import java.math.BigInteger; public class Main { public static void main(String[] args) { BigInteger integer = new BigInteger("11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111"); BigInteger integer2 = new BigInteger("222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222"); System.out.println(integer.max(integer2)); } }
콘솔 출력:
222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222
BigDecimal 반올림 동작
큰 숫자를 반올림하고 반올림 동작을 구성하는 것이 그렇게 간단하지 않기 때문에 이 항목에는 별도의 섹션이 있습니다. setScale() 메소드를 사용하여 BigDecimal 의 소수 자릿수를 설정할 수 있습니다 . 예를 들어 숫자 111.5555555555의 소수점 이하 세 자리를 원한다고 가정합니다. 그러나 숫자 3을 setScale() 메서드 에 인수로 전달하여 원하는 결과를 얻을 수 없습니다 . 위에서 언급했듯이 BigDecimal계산 정밀도에 대한 엄격한 요구 사항이 있는 숫자를 표현하기 위한 것입니다. 현재 형식에서 숫자는 소수점 이하 10자리입니다. 7개를 버리고 3개만 남기고자 합니다. 따라서 숫자 3 외에 반올림 모드를 통과해야 합니다. BigDecimal에는 총 8개의 반올림 모드가 있습니다. 많이! 그러나 계산의 정밀도를 미세하게 조정해야 한다면 필요한 모든 것을 갖추게 될 것입니다. BigDecimal 에서 제공하는 8가지 반올림 모드는 다음과 같습니다 .-
ROUND_CEILING — 반올림
111.5555555555 -> setScale(3, ROUND_CEILING) -> 111.556
-
ROUND_DOWN — 0으로 반올림
111.5555555555 -> setScale(3, ROUND_DOWN) -> 111.555
-
ROUND_FLOOR — 내림
111.5555555555 -> setScale(3, ROUND_FLOOR) -> 111.555
-
ROUND_HALF_UP — 소수점 이하 숫자 >= 0.5인 경우 반올림
0.55 -> setScale(1, ROUND_HALF_UP) -> 0.6 0.54 -> setScale(1, ROUND_HALF_UP) -> 0.5
-
ROUND_HALF_DOWN — 소수점 이하 숫자 > 0.5인 경우 반올림
0.55 -> setScale(1, ROUND_HALF_DOWN) -> 0.5 0.56 -> setScale(1, ROUND_HALF_DOWN) -> 0.6
-
ROUND_HALF_EVEN — 반올림은 소수점 왼쪽에 있는 숫자에 따라 달라집니다. 왼쪽의 숫자가 짝수이면 반올림됩니다. 소수점 왼쪽의 숫자가 홀수이면 반올림됩니다.
2.5 -> setScale(0, ROUND_HALF_EVEN) -> 2
소수점 왼쪽의 숫자는 2(짝수)입니다. 숫자는 내림합니다. 소수점 이하 자릿수 0을 원하므로 결과는 2입니다.
3.5 -> setScale(0, ROUND_HALF_EVEN) -> 4
소수점 왼쪽의 숫자는 3(홀수)입니다. 숫자는 반올림됩니다. 우리는 소수 자릿수가 0이기를 원하므로 결과는 4입니다.
-
ROUND_UNNECCESSARY — 이 모드는 반올림 모드를 메서드에 전달해야 하지만 숫자를 반올림할 필요가 없는 경우에 사용됩니다. ROUND_UNNECCESSARY 모드가 설정된 상태에서 숫자를 반올림하려고 하면 ArithmeticException이 발생합니다.
3.51 -> setScale(1, ROUND_UNNECCESSARY) -> ArithmeticException
-
ROUND_UP — 0에서 멀어지는 방향으로 반올림합니다.
111.5551 -> setScale(3, ROUND_UP) -> 111.556
큰 숫자 비교
이것은 또한 중요합니다. equals() 메서드를 사용하여 Java에서 개체를 비교한다는 것을 기억할 것입니다 . 구현은 언어 자체(표준 Java 클래스의 경우)에서 제공하거나 프로그래머가 재정의합니다. 그러나 BigDecimal 객체 의 경우 비교를 위해 equals() 메서드를 사용하는 것은 권장되지 않습니다. BigDecimal.equals() 메서드는 2개의 숫자가 동일한 값과 배율을 갖는 경우에만 true를 반환하기 때문입니다 . Double 및 BigDecimal 클래스 에 대한 equals() 메서드 의 동작을 비교해 보겠습니다 .
import java.math.BigDecimal;
public class Main {
public static void main(String[] args) {
Double a = 1.5;
Double b = 1.50;
System.out.println(a.equals(b));
BigDecimal x = new BigDecimal("1.5");
BigDecimal y = new BigDecimal("1.50");
System.out.println(x.equals(y));
}
}
콘솔 출력:
true
false
보시 다시피 BigDecimal 의 경우 숫자 1.5와 1.50이 같지 않은 것으로 나타났습니다! 이것은 정확히 BigDecimal 클래스 의 equals() 메소드 구현의 특성 때문이었습니다 . 두 개의 BigDecimal 객체를 보다 정확하게 비교하려면 compareTo() 메서드를 사용하는 것이 좋습니다 .
import java.math.BigDecimal;
public class Main {
public static void main(String[] args) {
BigDecimal x = new BigDecimal("1.5");
BigDecimal y = new BigDecimal("1.50");
System.out.println(x.compareTo(y));
}
}
콘솔 출력:
0
compareTo () 메서드는 0을 반환했으며 이는 1.5와 1.50이 같다는 것을 의미합니다. 그리고 이것은 우리가 예상한 결과입니다! :) 이것으로 오늘 수업을 마칩니다. 이제 작업으로 돌아갈 시간입니다! :)
GO TO FULL VERSION