오버플로우(overflow)란 타입이 허용하는 최대값을 벗어나는 것을 말한다. 반대로 언더플로우(underflow)란 타입이 허용하는 최소값을 벗어나는 것을 말한다.
정수 타입 연산에서 오버플로우 또는 언더플로우가 발생되면 실행 에러가 발생할 것 같지만, 그렇지 않고 해당 정수 타입의 최소값 또는 최대값으로 되돌아간다.
예를 들어 byte 타입일 경우 최대값 127에서 1을 더하면 128이 되어 오버플로우가 발생하여 연산 결과는 최소값인 -128이 된다. 마찬가지로 -128에서 1을 빼면 -129가 되어 언더플로우가 발생하는데, 연산 결과는 최대값인 127이 된다.
byte value = 127;
value++; //value 값에 1을 더함
System.out.println(value); //-128
value--; //value 값에 1을 뺌
System.out.println(value); //127
short, int, long 타입은 값의 범위만 다를 뿐 오버플로우 및 언더플로우가 발생했을 때 마찬가지로 최소값 또는 최대값으로 되돌아간다.
public class OverflowUnderflowExample {
public static void main(String[] args) {
byte var1 = 125;
for(int i=0; i<5; i++) { //{ }를 5번 반복 실행
var1++; //++ 연산은 var1의 값을 1 증가시킨다.
System.out.println("var1: " + var1);
//var1의 값이 126부터 1씩 증가하다 오버플로우가 발생하여
//126, 127, -128, -127, -126이 출력
}
System.out.println("-----------------------");
byte var2 = -125;
for(int i=0; i<5; i++) {
var2--; //-- 연산은 var2의 값을 1 감소시킨다.
System.out.println("var2: " + var2);
//var2의 값이 -126부터 1씩 감소하다 다운플로우가 발생하여
//-126, -127, -128, 127, 126이 출력
}
}
}
연산 과정 중에 발생하는 오버플로우와 언더플로우는 우리가 기대하는 값이 아니므로 항상 해당 타입의 범위 내에서 연산이 수행되도록 코딩에 신경써야 한다. 만약 연산 과정에서 int 타입에서 오버플로우 또는 언더플로우가 발생될 가능성이 있다면 long 타입으로 연산을 하도록 해야한다. 다음 예시 코드를 살펴보자.
int x = 1000000;
int y = 1000000;
int z = x * y; //z: -727379968
1000000 * 1000000은 10⁶*10⁶=10¹²이 되어 int 타입 허용 범위를 초과한 오버플로우가 발생한다. 이를 해결하여 올바른 값을 얻기 위해서는 변수 x와 y 중 최소 하나라도 long 타입이 되어야 하고, 변수 z가 long 타입이어야한다.
long x = 1000000;
long y = 1000000;
long z = x * y; //z: 1000000000000
'Language > Java' 카테고리의 다른 글
[Java] NaN과 Infinity 처리 (0) | 2022.10.14 |
---|---|
[Java] 정확한 계산 하는 방법 (0) | 2022.10.09 |
[Java] 부호/증감/산술 연산자 (0) | 2022.10.06 |
[Java] 키보드 입력 데이터를 변수에 저장 (0) | 2022.10.04 |
[Java] 변수 사용 범위와 콘솔로 변수값 출력 (0) | 2022.09.28 |