Arbeiten mit Floats
Nette\Utils\Floats ist eine statische Klasse mit nützlichen Funktionen zum Vergleichen von Dezimalzahlen.
Installation:
composer require nette/utils
Alle Beispiele setzen voraus, dass ein Alias erstellt wurde:
use Nette\Utils\Floats;
Motivation
Sie fragen sich vielleicht, warum überhaupt eine Klasse zum Vergleichen von Floats? Ich kann doch die Operatoren
<
, >
, ===
verwenden und bin fertig. Das stimmt nicht ganz. Was denken Sie, was dieser
Code ausgibt?
$a = 0.1 + 0.2;
$b = 0.3;
echo $a === $b ? 'same' : 'not same';
Wenn Sie den Code ausführen, werden einige von Ihnen sicherlich überrascht sein, dass das Programm not same
ausgegeben hat.
Bei mathematischen Operationen mit Dezimalzahlen kommt es aufgrund der Konvertierung zwischen dem Dezimal- und dem Binärsystem
zu Fehlern. Zum Beispiel ergibt 0.1 + 0.2
0.300000000000000044…
. Deshalb müssen wir beim Vergleich
einen kleinen Unterschied ab einer bestimmten Dezimalstelle tolerieren.
Und genau das macht die Klasse Floats
. Der folgende Vergleich funktioniert nun wie erwartet:
echo Floats::areEqual($a, $b) ? 'same' : 'not same'; // same
Beim Versuch, NAN
zu vergleichen, wird eine Ausnahme \LogicException
geworfen.
Die Klasse Floats
toleriert Unterschiede kleiner als 1e-10
. Wenn Sie mit höherer
Präzision arbeiten müssen, verwenden Sie stattdessen die BCMath-Bibliothek.
Vergleich von Floats
areEqual (float $a, float $b): bool
Gibt true
zurück, wenn $a
= $b
.
Floats::areEqual(10, 10.0); // true
isLessThan (float $a, float $b): bool
Gibt true
zurück, wenn $a
< $b
gilt.
Floats::isLessThan(9.5, 10.2); // true
Floats::isLessThan(INF, 10.2); // false
isLessThanOrEqualTo (float $a, float $b): bool
Gibt true
zurück, wenn $a
<= $b
gilt.
Floats::isLessThanOrEqualTo(9.5, 10.2); // true
Floats::isLessThanOrEqualTo(10.25, 10.25); // true
isGreaterThan (float $a, float $b): bool
Gibt true
zurück, wenn $a
> $b
gilt.
Floats::isGreaterThan(9.5, -10.2); // true
Floats::isGreaterThan(9.5, 10.2); // false
isGreaterThanOrEqualTo (float $a, float $b): bool
Gibt true
zurück, wenn $a
>= $b
gilt.
Floats::isGreaterThanOrEqualTo(9.5, 10.2); // false
Floats::isGreaterThanOrEqualTo(10.2, 10.2); // true
compare (float $a, float $b): int
Wenn $a
< $b
, gibt -1
zurück, wenn sie gleich sind, gibt 0
zurück, und
wenn $a
> $b
, gibt 1
zurück.
Kann beispielsweise mit der Funktion usort
verwendet werden.
$arr = [1, 5, 2, -3.5];
usort($arr, [Float::class, 'compare']);
// $arr ist jetzt [-3.5, 1, 2, 5]
Hilfsfunktionen
isZero (float $value): bool
Gibt true
zurück, wenn der Wert gleich Null ist.
Floats::isZero(0.0); // true
Floats::isZero(0); // true
isInteger (float $value): bool
Gibt true
zurück, wenn der Wert eine ganze Zahl ist.
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