28.4.06

Taşma (overflow) ve Sabrın Taşması

Taşma (overflow) her an başınıza gelebilecek oldukça sıradan bir olgudur. Fakat taşmayı farkedene kadar sabrınız ne kadar taşar o kadar önemli olan budur :) Aşağıdaki kod çok basit bir çarpma işleminden ibaret.

public class Main {
public static void main(String[] args) {
long l = 24 * 25 * 60 *60 * 1000 ;
System.out.println("Değer : " + l);
}
}

Programın çıktısı :
Değer : -2134967296

Herşeyin bir sınırı vardır biz de bu sınırı aştık(mı acaba) , olay bundan ibaret diyorsanız bir de şu koda bakın

public class Main {
public static void main(String[] args) {
long l = 24 * 25 * 60 *60 * 1000 ;
System.out.println("Değer : " + l);

//Burası Yeni
l = 24;
l *= 25;
l *= 60;
l *= 60;
l *= 1000;

System.out.println("Değer : " + l);
}
}

Çıktı olarak

Değer : -2134967296
Değer : -2134967296

gibi birşey bekliyorsanız biraz daha beklemeniz gerekecek. Çünkü gerçek çıktı

Değer : -2134967296
Değer : 2160000000

oluyor.Bu işte bir tuhaflık var ama ne :) Eğer kağıt kalem yardımıyla bu rakamları çarparsanız sonucun doğru olduğunu görürsünüz.Kaldı ki Javada long 64 bit ile gösterilir ve "2160000000" sayısı 2^63 -1 (64 bit ile gösterilebilecek en yüksek işaretli pozitif sayı) sınırının oldukça altındadır.
Olayın aslı şu ki ;

long l = 24 * 25 * 60 *60 * 1000 ;
işleminin sağ tarafındaki sayıların tamamı integer ve çarpma işlemi de sağ taraftaki en büyük tip olan integer üzerinde saklanıyor. Yani çarpım işlemi integer tipinde bir değişkende saklanıyor ve en son long tipine çevriliyor.Integer tipinde taşma olduktan sonra long tipine çevriliyor. İkinci kodda herhangi bir sorun olmamasının sebebi de bu
l *=25 (ve diğer ifadeler) şu ifadeye eşit l = l * 25 ;
Bu ifade de sağ taraftaki en büyük veri tipi "l" nin veri tipi olan long. İşlem long üzerinden yapılıyor. l * 25 çarpımı bir long değişkeninde saklanıyor orada sonra l değişkenine atanıyor ve herhangi bir sorun kalmıyor :)

Kodun en temiz hali sağ taraftaki sayılardan birini long yapmak ki bunun için sayının yanına "l" koymak yeterli.
long l = 24l * 25 * 60 *60 * 1000
System.out.println("Değer : " + l);

Küçük şeyler, küçük şeyler bizi uğraştıran küçük şeyler (Bu şarkı böyle değildi sanırım :))

1 comments:

eddybrinick90890398 said...
This comment has been removed by a blog administrator.