int
: 2,147,483,648 ~ 2,147,483,647long
: 9,223,372,036,854,775,808 ~ 9,223,372,036,854,775,807final int signum; // 부호 (1 (양수), 0, -1 (음수))
final int[] mag; // 값 (magnitue) // 배열로 되어 있음
BigInteger
정수로 표현할 수 있는 값을 넘은 수를 다룰 경우
내부적으로는 int 배열을 사용해서 값을 다루기 때문에 long 타입보다 훨씬 큰 값을 다룰 수 있음
하지만 성능은 떨어짐
final 으로 되어있기 때문에 불변 (immutable)이고 다른 모든 정수형처럼 값을 2의 보수 형태로 저장
import java.math.BigInteger;
import java.util.Arrays;
public class BigIntegerExample {
public static void main(String[] args) {
//// BigInteger 생성
// long longValue = 9223372036854775807; // stack over flow
BigInteger bigInteger1 = new BigInteger("9223372036854775807");
BigInteger bigInteger2 = new BigInteger("-9223372036854775807");
BigInteger bigInteger3 = new BigInteger("FFFF", 16); // 16진수 저장 가능
BigInteger bigInteger4 = BigInteger.valueOf(1234567890L); // Long 저장 가능
System.out.println("bigInteger1 = " + bigInteger1);
System.out.println("bigInteger1.signum() = " + bigInteger1.signum()); // 부호
System.out.println("bigInteger2 = " + bigInteger2);
System.out.println("bigInteger2.signum() = " + bigInteger2.signum());
System.out.println("bigInteger3 = " + bigInteger3); // 65535
System.out.println("bigInteger4 = " + bigInteger4); // 1234567890
System.out.println();
//// BigInteger ➡️️ 다른 타입
// toString()
String string1 = bigInteger1.toString();
String string2 = bigInteger2.toString();
String string3 = bigInteger3.toString();
String string4 = bigInteger4.toString(16);
System.out.println("string1 = " + string1);
System.out.println("string2 = " + string2);
System.out.println("string3 = " + string3);
System.out.println("string4 = " + string4);
System.out.println();
// toByteArray() : int 배열 -> byte 배열
byte[] bytes1 = bigInteger1.toByteArray();
byte[] bytes2 = bigInteger2.toByteArray();
byte[] bytes3 = bigInteger3.toByteArray();
byte[] bytes4 = bigInteger4.toByteArray();
// byte 배열 -> String
System.out.println("bytes1 = " + Arrays.toString(bytes1));
System.out.println("bytes2 = " + Arrays.toString(bytes2));
System.out.println("bytes3 = " + Arrays.toString(bytes3));
System.out.println("bytes4 = " + Arrays.toString(bytes4));
System.out.println();
// intValue()
int intValue1 = bigInteger1.intValue();
int intValue2 = bigInteger2.intValue();
int intValue3 = bigInteger3.intValue();
int intValue4 = bigInteger4.intValue();
System.out.println("intValue1 = " + intValue1);
System.out.println("intValue2 = " + intValue2);
System.out.println("intValue3 = " + intValue3);
System.out.println("intValue4 = " + intValue4);
System.out.println();
// longValue()
long longValue1 = bigInteger1.longValue();
long longValue2 = bigInteger2.longValue();
long longValue3 = bigInteger3.longValue();
long longValue4 = bigInteger4.longValue();
System.out.println("longValue1 = " + longValue1);
System.out.println("longValue2 = " + longValue2);
System.out.println("longValue3 = " + longValue3);
System.out.println("longValue4 = " + longValue4);
System.out.println();
// floatValue()
float floatValue1 = bigInteger1.floatValue();
float floatValue2 = bigInteger2.floatValue();
float floatValue3 = bigInteger3.floatValue();
float floatValue4 = bigInteger4.floatValue();
System.out.println("floatValue1 = " + floatValue1);
System.out.println("floatValue2 = " + floatValue2);
System.out.println("floatValue3 = " + floatValue3);
System.out.println("floatValue4 = " + floatValue4);
System.out.println();
// doubleValue()
double doubleValue1 = bigInteger1.doubleValue();
double doubleValue2 = bigInteger2.doubleValue();
double doubleValue3 = bigInteger3.doubleValue();
double doubleValue4 = bigInteger4.doubleValue();
System.out.println("doubleValue1 = " + doubleValue1);
System.out.println("doubleValue2 = " + doubleValue2);
System.out.println("doubleValue3 = " + doubleValue3);
System.out.println("doubleValue4 = " + doubleValue4);
System.out.println();
//// BigInteger 연산
// 객체 이기 때문에 메서드 있다
// add()
BigInteger add1 = bigInteger1.add(bigInteger2);
BigInteger add2 = bigInteger3.add(bigInteger4);
System.out.println("add1 = " + add1);
System.out.println("add2 = " + add2);
// subtract()
BigInteger sub1 = bigInteger1.subtract(bigInteger2);
BigInteger sub2 = bigInteger3.subtract(bigInteger4);
System.out.println("sub1 = " + sub1);
System.out.println("sub2 = " + sub2);
// multiply()
BigInteger mul1 = bigInteger1.multiply(bigInteger2);
BigInteger mul2 = bigInteger3.multiply(bigInteger4);
System.out.println("mul1 = " + mul1);
System.out.println("mul2 = " + mul2);
// divide()
BigInteger div1 = bigInteger1.divide(bigInteger2);
BigInteger div2 = bigInteger3.divide(bigInteger4);
System.out.println("div1 = " + div1);
System.out.println("div2 = " + div2);
// remainder() : 나머지
BigInteger remainder1 = bigInteger1.remainder(bigInteger2);
BigInteger remainder2 = bigInteger3.remainder(bigInteger4);
System.out.println("remainder1 = " + remainder1);
System.out.println("remainder2 = " + remainder2);
System.out.println();
//// BigInteger 비트 연산 메서드
BigInteger bigInteger = new BigInteger("11");
System.out.println("bigInteger.toString(2) = " + bigInteger.toString(2));
System.out.println("bigInteger.toString(2) = " + bigInteger.toString(8));
System.out.println("bigInteger.toString(2) = " + bigInteger.toString(16));
// bitCount()
// bitLength()
int numOfOne = bigInteger.bitCount();
int numOfZero = bigInteger.bitLength() - numOfOne;
System.out.println("numOfOne = " + numOfOne);
System.out.println("numOfZero = " + numOfZero);
// testBit()
boolean testBit = bigInteger.testBit(2);
System.out.println("testBit = " + testBit);
// val: 1 0 1 1
// idx: 3 2 1 0
// setBit()
BigInteger setBit = bigInteger.setBit(2);
System.out.println("setBit = " + setBit);
// clearBit()
BigInteger clearBit = bigInteger.clearBit(1);
System.out.println("clearBit = " + clearBit);
// flipBit()
BigInteger flipBit = bigInteger.flipBit(2);
System.out.println("flipBit = " + flipBit);
System.out.println();
System.out.println();
//// factorial 테스트
for (int i = 0; i < 100; i++) {
System.out.printf("factorial(%d) = %d \n", i, factorial(i));
System.out.printf("factorial(%d) = %d \n", i, factorial(new BigInteger(Integer.toString(i))));
System.out.println();
}
}
public static BigInteger factorial(BigInteger n) { // n! = 1 x 2 x 3 x 4 x ... n
if (n == null) return BigInteger.ZERO;
if (n.equals(BigInteger.ZERO)) return BigInteger.ONE;
else return n.multiply(factorial(n.subtract(BigInteger.ONE))); // n * factorial(n-1)
}
public static long factorial(long n) { // n! = 1 x 2 x 3 x 4 x ... n (20! 까지 가능)
if (n == 0) return 1;
else return n * factorial(n-1); // n * factorial(n-1)
}
}
double
타입으로 표현할 수 있는 값은 범위가 넓지만 정밀도가 최대 13자리 밖에 되지 않음BigDecimal
은 실수형과 달리 정수를 이용해서 실수 표현정수 x 10^(-scale),
scale - 0 ~ Integer.MAX_VALUE
private final BigInteger intVal; // 정수 (unscaled value) // int형 배열 사용
private final int scale; // 지수 (scale)
private transient int precision; // 정밀도 (precision) 정수의 자리수
// (cf) transient: Serialize하는 과정에 제외하고 싶은 변수 앞에 선언함 (보안상의 이유로)
// : 필드는 유지되지만 null로 초기화됨
// : 데이터 제외시 서비스 장애 이상이 없는지 고려해서 제외해야 함
BigDecimal(”123.45”)
→ 12345 x 10^(-2)로 표현BigDecimal: 정수를 이용해서 실수를 표현
private final BigInteger intVal; // 정수 (unscaled value)
private final int scale; // 지수 (scale)
private transient int precision; // 정밀도 (precision) 정수의 자리수
(cf) transient: Serialize하는 과정에 제외하고 싶은 변수 앞에 선언함 (보안상의 이유로)
: 필드는 유지되지만 null로 초기화됨
: 데이터 제외시 서비스 장애 이상이 없는지 고려해서 제외해야 함
실수의 오차는 10진 실수를 2진 실수로 정확히 변환할 수 없는 경우가 있기 때문에 발생하는 것임
오차가 없는 2진 정수로 변환해서 다룰 수 있음 => 정수 x 10^(-scale)
final 으로 되어있기 때문에 불변 (immutable)임
BigDecimal은 정수를 저장하는데 BigInteger을 사용함
import 해야함
import java.math.BigDecimal;
import java.math.BigInteger;
import java.math.MathContext;
import java.math.RoundingMode;
public class BigDecimalExample {
public static void main(String[] args) {
//// BigDecimal 분석
double doubleValue1 = 123.45;
System.out.println("doubleValue1 = " + doubleValue1);
BigDecimal bigDecimal1 = new BigDecimal("123.45"); // 12345 x 10^(-2)
System.out.println("bigDecimal1 = " + bigDecimal1);
// unscaledValue(), scale(), precision()
System.out.println("bigDecimal1.unscaledValue() = " + bigDecimal1.unscaledValue()); // 12345
System.out.println("bigDecimal1.scale() = " + bigDecimal1.scale()); // 2
System.out.println("bigDecimal1.precision() = " + bigDecimal1.precision()); // 5
System.out.println();
// 소수점 아래 14자리까지만 표현됨
double doubleValue2 = 123.45123124123123123123123123; // 실수가 길면 부동 소수점에 의해 잘림
System.out.println("doubleValue2 = " + doubleValue2);
BigDecimal bigDecimal2 = new BigDecimal("123.45123124123123123123123123"); // 12345 x 10^(-2) // 정확
System.out.println("bigDecimal2 = " + bigDecimal2);
System.out.println("bigDecimal2.unscaledValue() = " + bigDecimal2.unscaledValue());
System.out.println("bigDecimal2.scale() = " + bigDecimal2.scale());
System.out.println("bigDecimal2.precision() = " + bigDecimal2.precision());
System.out.println();
//// BigDecimal 생성 => "" 으로 생성 (데이터의 손상 없도록)
BigDecimal bigDecimal3 = new BigDecimal("123.4567890"); // "" 으로 생성
BigDecimal bigDecimal4 = new BigDecimal(123.4567890); // 그냥 double로 생성하면 부동 소수점에 의해 부정확
BigDecimal bigDecimal5 = new BigDecimal(1234567890);
// 만약 double을 인자로 주고 싶을 경우 valueOf() 사용
BigDecimal bigDecimal6 = BigDecimal.valueOf(123.4567890);
BigDecimal bigDecimal7 = BigDecimal.valueOf(1234567890);
System.out.println("bigDecimal3 = " + bigDecimal3);
System.out.println("bigDecimal4 = " + bigDecimal4);
System.out.println("bigDecimal5 = " + bigDecimal5);
System.out.println("bigDecimal6 = " + bigDecimal6);
System.out.println("bigDecimal7 = " + bigDecimal7);
System.out.println();
//// BigDecimal ➡️️ String
// toString()
// toPlainString()
// toEngineeringString()
BigDecimal bigDecimal8 = new BigDecimal(1.0e-30); // 지수를 이용해서 초기화 가능
String string1 = bigDecimal8.toString(); // 생성자로 전달받은 값 그대로 반환
String plainString1 = bigDecimal8.toPlainString(); // 생성자로 전달받은 값을 지수표현없이 반환
String engineerString1 = bigDecimal8.toEngineeringString(); // 지수표현이 있으면 엔지니어링 표기법으로 반환 (거듭제곱이 3의 배수)
System.out.println("string1 = " + string1);
System.out.println("plainString1 = " + plainString1);
System.out.println("engineerString1 = " + engineerString1);
System.out.println();
BigDecimal bigDecimal9 = new BigDecimal(0.0001e-20); // 지수를 이용해서 초기화 가능
String string2 = bigDecimal9.toString(); // 생성자로 전달받은 값 그대로 반환
String plainString2 = bigDecimal9.toPlainString(); // 생성자로 전달받은 값을 지수표현없이 반환
String engineerString2 = bigDecimal9.toEngineeringString(); // 지수표현이 있으면 엔지니어링 표기법으로 반환 (거듭제곱이 3의 배수)
System.out.println("string2 = " + string2);
System.out.println("plainString2 = " + plainString2);
System.out.println("engineerString2 = " + engineerString2);
System.out.println();
//// BigDecimal ➡️️ 다른 타입
// valueOf()
BigDecimal bigDecimal10 = new BigDecimal("123.45123124123123123123123123");
BigDecimal bigDecimal11 = new BigDecimal(123.45123124123123123123123123); // BigDecimal(double)은 double가 부정확하기 때문에 예측 불가
BigDecimal bigDecimal12 = new BigDecimal(1234567890);
BigDecimal bigDecimal13 = BigDecimal.valueOf(123.45123124123123123123123123); // 만약 double을 인자로 주고 싶을 경우 valueOf(double) 사용
BigDecimal bigDecimal14 = BigDecimal.valueOf(1234567890);
System.out.println("bigDecimal10 = " + bigDecimal10);
System.out.println("bigDecimal11 = " + bigDecimal11);
System.out.println("bigDecimal12 = " + bigDecimal12);
System.out.println("bigDecimal13 = " + bigDecimal13);
System.out.println("bigDecimal14 = " + bigDecimal14);
System.out.println();
// byteValue()
byte byte10 = bigDecimal10.byteValue();
byte byte11 = bigDecimal11.byteValue();
byte byte12 = bigDecimal12.byteValue();
byte byte13 = bigDecimal13.byteValue();
byte byte14 = bigDecimal14.byteValue();
System.out.println("byte10 = " + byte10);
System.out.println("byte11 = " + byte11);
System.out.println("byte12 = " + byte12);
System.out.println("byte13 = " + byte13);
System.out.println("byte14 = " + byte14);
System.out.println();
// intValue()
int intValue10 = bigDecimal10.intValue();
int intValue11 = bigDecimal11.intValue();
int intValue12 = bigDecimal12.intValue();
int intValue13 = bigDecimal13.intValue();
int intValue14 = bigDecimal14.intValue();
System.out.println("intValue10 = " + intValue10);
System.out.println("intValue11 = " + intValue11);
System.out.println("intValue12 = " + intValue12);
System.out.println("intValue13 = " + intValue13);
System.out.println("intValue14 = " + intValue14);
System.out.println();
// longValue()
long longValue10 = bigDecimal10.longValue();
long longValue11 = bigDecimal11.longValue();
long longValue12 = bigDecimal12.longValue();
long longValue13 = bigDecimal13.longValue();
long longValue14 = bigDecimal14.longValue();
System.out.println("longValue10 = " + longValue10);
System.out.println("longValue11 = " + longValue11);
System.out.println("longValue12 = " + longValue12);
System.out.println("longValue13 = " + longValue13);
System.out.println("longValue14 = " + longValue14);
System.out.println();
// floatValue()
float floatValue10 = bigDecimal10.floatValue();
float floatValue11 = bigDecimal11.floatValue();
float floatValue12 = bigDecimal12.floatValue();
float floatValue13 = bigDecimal13.floatValue();
float floatValue14 = bigDecimal14.floatValue();
System.out.println("floatValue10 = " + floatValue10);
System.out.println("floatValue11 = " + floatValue11);
System.out.println("floatValue12 = " + floatValue12);
System.out.println("floatValue13 = " + floatValue13);
System.out.println("floatValue14 = " + floatValue14);
System.out.println();
// doubleValue()
double doubleValue10 = bigDecimal10.doubleValue();
double doubleValue11 = bigDecimal11.doubleValue();
double doubleValue12 = bigDecimal12.doubleValue();
double doubleValue13 = bigDecimal13.doubleValue();
double doubleValue14 = bigDecimal14.doubleValue();
System.out.println("doubleValue10 = " + doubleValue10);
System.out.println("doubleValue11 = " + doubleValue11);
System.out.println("doubleValue12 = " + doubleValue12);
System.out.println("doubleValue13 = " + doubleValue13);
System.out.println("doubleValue14 = " + doubleValue14);
System.out.println();
// toBigInteger()
BigInteger bigInteger10 = bigDecimal10.toBigInteger();
BigInteger bigInteger11 = bigDecimal11.toBigInteger();
BigInteger bigInteger12 = bigDecimal12.toBigInteger();
BigInteger bigInteger13 = bigDecimal13.toBigInteger();
BigInteger bigInteger14 = bigDecimal14.toBigInteger();
System.out.println("bigInteger10 = " + bigInteger10);
System.out.println("bigInteger11 = " + bigInteger11);
System.out.println("bigInteger12 = " + bigInteger12);
System.out.println("bigInteger13 = " + bigInteger13);
System.out.println("bigInteger14 = " + bigInteger14);
System.out.println();
//// BigDecimal 연산
// add, subtract, multiply, divide, remainder
BigDecimal bigDecimal15 = new BigDecimal("123.456");
BigDecimal bigDecimal16 = new BigDecimal("0.1");
BigDecimal add = bigDecimal15.add(bigDecimal16);
BigDecimal sub = bigDecimal15.subtract(bigDecimal16);
BigDecimal mul = bigDecimal15.multiply(bigDecimal16);
BigDecimal div = bigDecimal15.divide(bigDecimal16);
BigDecimal remainder = bigDecimal15.remainder(bigDecimal16);
System.out.println("bigDecimal15 = " + bigDecimal15 + ", bigDecimal15.unscaledValue() = " +
bigDecimal15.unscaledValue() + ", bigDecimal15.scale() = " + bigDecimal15.scale() + ", bigDecimal15.precision() = " + bigDecimal15.precision());
System.out.println("bigDecimal16 = " + bigDecimal16 + ", bigDecimal16.unscaledValue() = " +
bigDecimal16.unscaledValue() + ", bigDecimal16.scale() = " + bigDecimal16.scale() + ", bigDecimal16.precision() = " + bigDecimal16.precision());
System.out.println("=============================================================================================================");
System.out.println("add = " + add + ", add.unscaledValue() = " + add.unscaledValue() + ", add.scale() = " + add.scale() + ", add.precision() = " + add.precision());
System.out.println("sub = " + sub + ", sub.unscaledValue() = " + sub.unscaledValue() + ", sub.scale() = " + sub.scale() + ", sub.precision() = " + sub.precision());
System.out.println("mul = " + mul + ", mul.unscaledValue() = " + mul.unscaledValue() + ", mul.scale() = " + mul.scale() + ", mul.precision() = " + mul.precision());
System.out.println("div = " + div + ", div.unscaledValue() = " + div.unscaledValue() + ", div.scale() = " + div.scale() + ", div.precision() = " + div.precision());
System.out.println("remainder = " + remainder + ", remainder.unscaledValue() = " + remainder.unscaledValue() + ", remainder.scale() = " + remainder.scale() + ", remainder.precision() = " + remainder.precision());
System.out.println();
// 반올림 모드 (divide(), setScale())
// roundingMode - 나눗셈 결과 어떻게 반올림 할 것인가
// - CEILING: 올림
// - FLOOR: 내림
// - UP: 양수일 때는 올림, 음수일 때는 내림
// - DOWN: 양수일 때는 내림, 음수일 때는 내림
// - HALF_UP: 반올림 (5이상 올림, 5미만 버림)
// - HALF_EVEN: 반올림 (반올림 자리의 값이 짝수면 HALF_DOWN, 홀수면 HALF_UP)
// - HALF_DOWN: 반올림 (6이상 올림, 6미만 버림)
// - UNNECESSARY: 나눗셈 결과가 딱 떨어지는 수가 아니면 ArithmeticException 발생
// (*) divide()한 나눗셈 결과가 무한 소수인 경우, 반올림 모드를 지정해주지 않으면 ArithmeticException 발생
BigDecimal bigDecimal17 = new BigDecimal("123.4567890");
BigDecimal bigDecimal18 = new BigDecimal("0.1");
System.out.println("bigDecimal17 = " + bigDecimal17);
System.out.println("bigDecimal18 = " + bigDecimal18);
BigDecimal divide1 = bigDecimal17.divide(bigDecimal18, 2, RoundingMode.HALF_UP); // 정밀도 2에서 반올림
BigDecimal divide2 = bigDecimal17.divide(bigDecimal18, new MathContext(2, RoundingMode.HALF_UP)); // 정밀도 2에서 반올림
System.out.println("divide1 = " + divide1);
System.out.println("divide2 = " + divide2.toPlainString());
}
}