@
mrmarman bey teknik açıklamasını yaptı. Yapay zekaya sorup herkesin öğrenebileceği bir şeyi, hem konuya katkı sağlamak hemde konuyu okumak için buraya kadar gelenlerin işini kolaylaştırmak için AI cevabını buraya ekliyorum.
//----Yapay zeka cevabı----------
Bu durum, bilgisayar bilimlerinde
"Floating Point Precision" (Kayan Noktalı Sayı Hassasiyeti) olarak bilinen çok yaygın ve can sıkıcı bir durumdur. Görünüşte 2.40 olan bir sayı, bellekte tam olarak 2.40 olarak saklanamayabilir.
Sorunun Nedeni
Bilgisayarlar sayıları ikilik (binary) sistemde saklar. Bazı ondalıklı sayılar (0.1, 0.4, 2.4 gibi) ikilik sistemde sonsuz bir devirli sayıya dönüşür.
Senin örneğinde:
- NumberBox1.Value(Double) tam olarak 2.4000000000000000 yerine 2.3999999999999999 gibi çok küçük bir farkla saklanıyor olabilir.
- if (dval < 2.40) kontrolü yaptığında, sağ taraftaki 2.40 sabiti de derleyici tarafından farklı bir hassasiyetle ele alınabilir.
- Sonuçta 2.3999... < 2.40 ifadesi doğru (True) kabul edilir ve "Küçük" sonucunu alırsın.
Çözüm Yolları
Bu sorunu çözmek için Delphi'de (ve genel programlamada) üç temel yaklaşım vardır:
1.SameValue Fonksiyonunu Kullanmak (En Doğru Yol)
Delphi'nin System.Math kütüphanesinde bulunan SameValue fonksiyonu, iki ondalıklı sayının "yeterince yakın" olup olmadığını kontrol eder.
uses
System.Math; // Bunu interface veya implementation kısmına eklemelisin.
function TForm1.kontrol(dval: double): string;
begin
// Epsilon (hata payı) kullanarak karşılaştırma yapar
if SameValue(dval, 2.40, 0.0001) or (dval > 2.40) then
result := 'Küçük Değil'
else
result := 'Küçük';
end;
2. Sayıyı Tam Sayıya Çevirerek Karşılaştırmak
Eğer virgülden sonraki basamak sayın belliyse (örneğin 2 basamak), her iki tarafı da 100 ile çarpıp tam sayıya (Integer) çevirerek karşılaştırabilirsin.
function TForm1.kontrol(dval: double): string;
begin
// 2.40 -> 240 olur. Hassasiyet sorunu ortadan kalkar.
if Trunc(dval * 100) < Trunc(2.40 * 100) then
result := 'Küçük'
else
result := 'Küçük Değil';
end;
3. Currency Veri Tipini Kullanmak
Eğer finansal bir hesaplama yapıyorsan, Delphi'de Double yerine Currency tipini kullanmanı öneririm. Currency tipi arka planda tam sayı olarak tutulur ve bu tür kayan nokta hatalarına neden olmaz.
function TForm1.kontrol(dval: Currency): string; // Parametreyi Currency yap
begin
if (dval < 2.40) then
result := 'Küçük'
else
result := 'Küçük Değil';
end;