Nah, sejauh tipe integer primitif berjalan, Java tidak menangani Over / Underflow sama sekali (untuk float dan double behavior berbeda, ia akan menyiram ke +/- infinity seperti yang diamanatkan oleh IEEE-754).
Saat menambahkan dua int, Anda tidak akan mendapatkan indikasi kapan terjadi overflow. Metode sederhana untuk memeriksa overflow adalah dengan menggunakan tipe lebih besar berikutnya untuk benar-benar melakukan operasi dan memeriksa apakah hasilnya masih dalam kisaran untuk tipe sumber:
public int addWithOverflowCheck(int a, int b) {
// the cast of a is required, to make the + work with long precision,
// if we just added (a + b) the addition would use int precision and
// the result would be cast to long afterwards!
long result = ((long) a) + b;
if (result > Integer.MAX_VALUE) {
throw new RuntimeException("Overflow occured");
} else if (result < Integer.MIN_VALUE) {
throw new RuntimeException("Underflow occured");
}
// at this point we can safely cast back to int, we checked before
// that the value will be withing int's limits
return (int) result;
}
Apa yang akan Anda lakukan sebagai pengganti klausa throw, tergantung pada persyaratan aplikasi Anda (throw, flush to min / max atau hanya login apa saja). Jika Anda ingin mendeteksi kelebihan pada operasi yang lama, Anda kurang beruntung dengan primitif, gunakan BigInteger sebagai gantinya.
Sunting (2014-05-21): Karena pertanyaan ini tampaknya cukup sering dirujuk dan saya harus menyelesaikan masalah yang sama, cukup mudah untuk mengevaluasi kondisi overflow dengan metode yang sama CPU akan menghitung flag V-nya.
Pada dasarnya ini adalah ekspresi boolean yang melibatkan tanda dari kedua operan serta hasilnya:
/**
* Add two int's with overflow detection (r = s + d)
*/
public static int add(final int s, final int d) throws ArithmeticException {
int r = s + d;
if (((s & d & ~r) | (~s & ~d & r)) < 0)
throw new ArithmeticException("int overflow add(" + s + ", " + d + ")");
return r;
}
Dalam java lebih mudah untuk menerapkan ekspresi (dalam if) ke seluruh 32 bit, dan periksa hasilnya menggunakan <0 (ini akan secara efektif menguji bit tanda). Prinsip kerjanya persis sama untuk semua tipe primitif integer , mengubah semua deklarasi dalam metode di atas menjadi lama membuatnya bekerja lama.
Untuk jenis yang lebih kecil, karena konversi implisit ke int (lihat JLS untuk operasi bitwise untuk detail), alih-alih memeriksa <0, pemeriksaan perlu menutupi bit tanda secara eksplisit (0x8000 untuk operan pendek, 0x80 untuk operan byte, sesuaikan gips dan deklarasi parameter dengan tepat):
/**
* Subtract two short's with overflow detection (r = d - s)
*/
public static short sub(final short d, final short s) throws ArithmeticException {
int r = d - s;
if ((((~s & d & ~r) | (s & ~d & r)) & 0x8000) != 0)
throw new ArithmeticException("short overflow sub(" + s + ", " + d + ")");
return (short) r;
}
(Perhatikan bahwa contoh di atas menggunakan kebutuhan ekspresi untuk mengurangi deteksi luapan)
Jadi bagaimana / mengapa ungkapan boolean ini bekerja? Pertama, beberapa pemikiran logis mengungkapkan bahwa luapan hanya dapat terjadi jika tanda-tanda dari kedua argumen itu sama. Karena, jika satu argumen negatif dan satu positif, hasil (dari tambah) harus mendekati nol, atau dalam kasus ekstrim satu argumen adalah nol, sama dengan argumen lainnya. Karena argumen sendiri tidak dapat membuat kondisi overflow, jumlah mereka juga tidak dapat membuat overflow.
Jadi apa yang terjadi jika kedua argumen memiliki tanda yang sama? Mari kita lihat kasus keduanya positif: menambahkan dua argumen yang membuat jumlah lebih besar dari jenis MAX_VALUE, akan selalu menghasilkan nilai negatif, sehingga terjadi overflow jika arg1 + arg2> MAX_VALUE. Sekarang nilai maksimum yang bisa dihasilkan adalah MAX_VALUE + MAX_VALUE (kasus ekstrem kedua argumen adalah MAX_VALUE). Untuk byte (contoh) yang berarti 127 + 127 = 254. Melihat representasi bit dari semua nilai yang dapat dihasilkan dari menambahkan dua nilai positif, orang menemukan bahwa yang overflow (128 hingga 254) semuanya memiliki bit 7 set, sementara semua yang tidak meluap (0 hingga 127) telah dihapus bit 7 (paling atas, tanda). Itulah tepatnya yang diperiksa bagian pertama (kanan) dari ekspresi:
if (((s & d & ~r) | (~s & ~d & r)) < 0)
(~ s & ~ d & r) menjadi benar, hanya jika , kedua operan (s, d) positif dan hasilnya (r) negatif (ekspresi bekerja pada semua 32 bit, tetapi hanya bit yang kami tertarik adalah bit paling atas (tanda), yang diperiksa terhadap <0).
Sekarang jika kedua argumen negatif, jumlah mereka tidak akan pernah bisa mendekati nol daripada argumen mana pun, jumlahnya harus lebih dekat ke minus tanpa batas. Nilai paling ekstrem yang dapat kami hasilkan adalah MIN_VALUE + MIN_VALUE, yang (sekali lagi sebagai contoh byte) menunjukkan bahwa untuk setiap nilai rentang (-1 hingga -128) bit tanda diatur, sementara kemungkinan nilai melimpah yang lain (-129 hingga -256 ) memiliki tanda sedikit dihapus. Jadi tanda hasil lagi mengungkapkan kondisi melimpah. Itulah yang setengah bagian kiri (s & d & r) memeriksa untuk kasus di mana kedua argumen (s, d) negatif dan hasil yang positif. Logikanya sebagian besar setara dengan kasus positif; semua pola bit yang dapat dihasilkan dari menambahkan dua nilai negatif akan memiliki bit tanda dihapus jika dan hanya jika terjadi underflow.