Underflow là gì?
Khi kết quả phép toán nhỏ hơn giá trị nhỏ nhất có thể biểu diễn của kiểu dữ liệu (ví dụ Integer.MIN_VALUE = -2,147,483,648). Java không ném exception tự động cho integer underflow/overflow – nó wrap-around (tràn vòng). Programmer tự chịu trách nhiệm kiểm tra.
Ví dụ: Phát hiện underflow khi cộng 2 số int âm lớn
public class UnderflowCheckDemo {
public static void main(String[] args) {
int num1 = -2147483648; // Integer.MIN_VALUE
int num2 = -1;
System.out.println("Num1: " + num1);
System.out.println("Num2: " + num2);
// Dùng long để kiểm tra trước khi cast về int
long sum = (long) num1 + (long) num2; // -2147483649
if (sum < Integer.MIN_VALUE) {
throw new ArithmeticException("Underflow occurred! Kết quả < Integer.MIN_VALUE");
}
System.out.println("Tổng (int): " + (int) sum); // dòng này không chạy
}
}
Kết quả
Num1: -2147483648
Num2: -1
Exception in thread "main" java.lang.ArithmeticException: Underflow occurred! Kết quả < Integer.MIN_VALUE
at UnderflowCheckDemo.main(UnderflowCheckDemo.java:9)
Các kỹ thuật phòng tránh
- Dùng
longhoặcBigIntegercho tính toán trung gian. - Kiểm tra trước:
if (a < 0 && b < 0 && a < Integer.MIN_VALUE - b) throw ... - Thư viện:
Math.addExact(),Math.subtractExact(),Math.multiplyExact()(Java 8+) – némArithmeticExceptionkhi overflow/underflow.
Lưu ý: Float/double underflow → kết quả thành 0.0 (gradual underflow) hoặc subnormal numbers, không ném exception.