연산 작업을 수행했을때 타입이 허용되는 범위 , 즉 최대값을 벗어나는 것을 말한다
컴파일링 에러가 아닌 해당 정수 타입의 최소값 으로 되돌아 간다
byte b = 127;
b++;
System.out.println(b); // -128 출력
byte 타입의 경우 범위가 -128 ~ 127인데 1을 증가 시키면 128이 되어 오버플로우가 발생한다.
그래서 최대값에서 한칸 뒤로 밀려지게 되어 -128 이 된다
언더플로우도 마찬가지로 타입의 최소값 아래의 값이 나올때 해당 정수 타입의 최대값으로 되돌아간다.
byte b = -128;
b--;
System.out.println(b); // 127 출력
마찬가지로 -128 에서 1을 빼면 언더플로우가 발생하여 byte의 최대값인 127이 된다.
short , int , long 타입도 타입들의 범위에 따라 언더플로우/오버플로우가 발생했을때 똑같이
최소값 / 최대값으로 되돌아간다
만약 int 타입으로 연산과정 중 언더플로우/오버플로우 발생 가능성이 있다면 long 타입으로 연산을 하자!
long 타입의 허용 범위
최솟값: -9,223,372,036,854,775,808 (-2^63)
최댓값: 9,223,372,036,854,775,807 (2^63 - 1)
public class OverflowUnderflowExample {
public static void main(String[] args) {
// 정수 오버플로우 예제
System.out.println("=== 정수 오버플로우 ===");
byte byteValue = 126;
for (int i = 0; i < 5; i++) {
byteValue++;
System.out.println("byteValue 증가 " + i + "번째: " + byteValue);
// 127 이후에 -128로 오버플로우 발생
}
// 정수 언더플로우 예제
System.out.println("\n=== 정수 언더플로우 ===");
byte underValue = -126;
for (int i = 0; i < 5; i++) {
underValue--;
System.out.println("underValue 감소 " + i + "번째: " + underValue);
// -128 이후에 127로 언더플로우 발생
}
// 다른 타입(int) 오버플로우 예제
System.out.println("\n=== int 오버플로우 ===");
int maxInt = Integer.MAX_VALUE; // 2147483647
for (int i = 0; i < 3; i++) {
System.out.println("maxInt + " + i + ": " + (maxInt + i));
// 최댓값을 넘어서면 오버플로우로 음수가 됨
}
}
}
코드의 실행 결과를 보면 타입범위 보다 초과 / 미만이 되었을때 오버/언더 플로우가 발생하는것을 확인할 수 있다
=== 정수 오버플로우 ===
byteValue 증가 0번째: 127
byteValue 증가 1번째: -128 <-- 오버플로우 발생
byteValue 증가 2번째: -127
byteValue 증가 3번째: -126
byteValue 증가 4번째: -125
=== 정수 언더플로우 ===
underValue 감소 0번째: -127
underValue 감소 1번째: -128
underValue 감소 2번째: 127 <-- 언더플로우 발생
underValue 감소 3번째: 126
underValue 감소 4번째: 125
=== int 오버플로우 ===
maxInt + 0: 2147483647
maxInt + 1: -2147483648 <-- 오버플로우 발생
maxInt + 2: -2147483647