Kayan Noktalı Sayılarla Çalışma
Nette\Utils\Floats, kayan noktalı sayıları karşılaştırmaya yarayan kullanışlı fonksiyonlar içeren statik bir sınıftır.
Kurulum:
composer require nette/utils
Tüm örnekler, aşağıdaki sınıf takma adının tanımlandığını varsayar:
use Nette\Utils\Floats;
Neden Gerekli
Kayan noktalı sayıları karşılaştırmak için neden ayrı bir sınıfa ihtiyaç duyduğumuzu merak ediyor olabilirsiniz.
Sonuçta <, >, === operatörlerini kullanırsınız ve iş biter, öyle değil mi?
Pek değil. Sizce bu kod ne yazdırır?
$a = 0.1 + 0.2;
$b = 0.3;
echo $a === $b ? 'aynı' : 'aynı değil';
Kodu çalıştırırsanız, programın aynı değil yazdırması bazılarınızı şaşırtabilir.
Kayan noktalı sayılarla yapılan matematiksel işlemler, ondalık ve ikili gösterim arasındaki dönüşüm nedeniyle
duyarlılık hatalarına yol açabilir. Örneğin 0.1 + 0.2 işleminin sonucu 0.300000000000000044…
gibi bir şey olur. Bu yüzden kayan noktalı sayıları karşılaştırırken küçük bir farka, bir epsilon değerine tolerans
göstermemiz gerekir.
Floats sınıfının yaptığı da tam olarak budur. Aşağıdaki karşılaştırma artık beklendiği gibi
çalışır:
echo Floats::areEqual($a, $b) ? 'aynı' : 'aynı değil'; // aynı
NAN değerini karşılaştırmaya çalışmak \LogicException fırlatır.
Floats sınıfı yaklaşık 1e-10 göreli duyarlılıkla karşılaştırma yapar. Daha
yüksek duyarlılıkla çalışmanız gerekiyorsa, bunun yerine BCMath kütüphanesini kullanmayı düşünün.
Kayan Noktalı Sayı Karşılaştırma
areEqual (float $a, float $b): bool
$a = $b ise true döndürür.
Floats::areEqual(10, 10.0); // true
isLessThan (float $a, float $b): bool
$a < $b ise true döndürür.
Floats::isLessThan(9.5, 10.2); // true
Floats::isLessThan(INF, 10.2); // false
isLessThanOrEqualTo (float $a, float $b): bool
$a <= $b ise true döndürür.
Floats::isLessThanOrEqualTo(9.5, 10.2); // true
Floats::isLessThanOrEqualTo(10.25, 10.25); // true
isGreaterThan (float $a, float $b): bool
$a > $b ise true döndürür.
Floats::isGreaterThan(9.5, -10.2); // true
Floats::isGreaterThan(9.5, 10.2); // false
isGreaterThanOrEqualTo (float $a, float $b): bool
$a >= $b ise true döndürür.
Floats::isGreaterThanOrEqualTo(9.5, 10.2); // false
Floats::isGreaterThanOrEqualTo(10.2, 10.2); // true
compare (float $a, float $b): int
$a < $b ise -1, eşitlerse 0, $a > $b ise
1 döndürür.
Örneğin usort() fonksiyonuyla birlikte kullanılabilir.
$arr = [1, 5, 2, -3.5];
usort($arr, [Floats::class, 'compare']);
// $arr artık [-3.5, 1, 2, 5]
Yardımcı Fonksiyonlar
isZero (float $value): bool
Değer sıfırsa true döndürür.
Floats::isZero(0.0); // true
Floats::isZero(0); // true
isInteger (float $value): bool
Değer bir tam sayıysa true döndürür.
Floats::isInteger(0); // true
Floats::isInteger(0.0); // true
Floats::isInteger(-5.0); // true
Floats::isInteger(-5.1); // false
Floats::isInteger(INF); // false
Floats::isInteger(NAN); // false