Float'larla Çalışma
Nette\Utils\Floats, ondalık sayıları karşılaştırmak için yararlı fonksiyonlar içeren statik bir sınıftır.
Kurulum:
composer require nette/utils
Tüm örnekler, oluşturulmuş bir takma ad varsayar:
use Nette\Utils\Floats;
Motivasyon
Float'ları karşılaştırmak için neden bir sınıfa ihtiyacım var diye düşünüyor olabilirsiniz? Sonuçta
<
, >
, ===
operatörlerini kullanabilirim ve işim biter. Bu tam olarak doğru değil.
Sizce bu kod ne yazdırır?
$a = 0.1 + 0.2;
$b = 0.3;
echo $a === $b ? 'aynı' : 'aynı değil'; // same -> aynı, not same -> aynı değil
Kodu çalıştırırsanız, bazılarınız programın aynı değil
yazdırmasına kesinlikle şaşıracaktır.
Ondalık sayılarla yapılan matematiksel işlemlerde, onluk ve ikilik sistemler arasındaki dönüşüm nedeniyle hatalar
oluşur. Örneğin, 0.1 + 0.2
sonucu 0.300000000000000044…
olur. Bu nedenle, karşılaştırma
yaparken belirli bir ondalık basamaktan sonra küçük bir farkı tolere etmemiz gerekir.
Ve işte Floats
sınıfı tam olarak bunu yapar. Aşağıdaki karşılaştırma artık beklendiği gibi
çalışacaktır:
echo Floats::areEqual($a, $b) ? 'aynı' : 'aynı değil'; // aynı
NAN
karşılaştırmaya çalışıldığında \LogicException
istisnası fırlatır.
Floats
sınıfı 1e-10
'dan küçük farkları tolere eder. Daha yüksek hassasiyetle
çalışmanız gerekiyorsa, bunun yerine BCMath kütüphanesini kullanın.
Float Karşılaştırması
areEqual (float $a, float $b): bool
Eğer $a
= $b
ise true
döndürür.
Floats::areEqual(10, 10.0); // true
isLessThan (float $a, float $b): bool
Eğer $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
Eğer $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
Eğer $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
Eğer $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
Eğer $a
< $b
ise -1
, eğer eşitlerse 0
ve eğer $a
>
$b
ise 1
döndürür.
Örneğin usort
fonksiyonu ile kullanılabilir.
$arr = [1, 5, 2, -3.5];
usort($arr, [Floats::class, 'compare']);
// $arr şimdi [-3.5, 1, 2, 5]
Yardımcı Fonksiyonlar
isZero (float $value): bool
Değer sıfıra eşitse true
döndürür.
Floats::isZero(0.0); // true
Floats::isZero(0); // true
isInteger (float $value): bool
Değer bir tamsayı ise 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