1. Einleitung
Für die Ermittlung der Anzahl der Nachkommastellen einer Zahl existiert keine feste Funktion in PHP. Nachfolgend werden daher zwei mögliche eigene Implementierungen vorgestellt. Dabei ist zu berücksichtigen, dass Floats/Doubles „von Natur aus” ungenau sind und daher die berechnete Anzahl der Nachkommastellen vom erwarteten Wert abweichen kann. Die Ergebnisse dürfen daher nur als grobe Richtwerte angesehen werden, die nicht immer richtig sind.
2. Berechnung der Nachkommastellen über String-Umwandlung
In diesem Beispiel wird eine Funktion „decimalPlaces()” definiert, welche einen Float-Wert erwartet. Dieser Float-Wert wird in einen String umgewandelt. Es wird nach dem letzten Punkt im String gesucht und anhand dessen Position im Verhältnis zur Gesamtlänge des Strings die Anzahl der Nachkommastellen berechnet. Wird statt dem Punkt ein Komma als Trennzeichen verwendet, dann muss die Funktion entsprechend angepasst werden. Bei Zahlen mit sehr vielen Stellen werden falsche Ergebnisse zurückgegeben. (Das schließt auch Vorkommastellen mit ein!)
<?php $numbers = array(1, 1.0, 1.424000000000, 3.141, 0.123456789, 1e10, 13134.4324234, 2389.1111111111111, 99999999.2222222222); function decimalPlaces($number) { $str = strval($number); $pos = strrpos($number, '.'); return ($pos===false ? 0 : strlen($str)-$pos-1); } foreach ($numbers as $number) { echo $number.": ".decimalPlaces($number)."\n"; } ?>
1: 0 1: 0 1.424: 3 3.141: 3 0.123456789: 9 10000000000: 0 13134.4324234: 7 2389.1111111111: 10 99999999.222222: 6
3. Subtraktion kombiniert mit String-Länge
Im nächsten Beispiel wird „decimalPlaces()” angepasst, sodass die vorhandenen Vorkommastellen vor der String-Umwandlung abgezogen werden. Dazu wird von der übergebenen Zahl ihr Integerwert abgezogen. (Also der Wert der Zahl, ohne Nachkommastellen.) Anschließend wird geprüft, ob die Zahl überhaupt Nachkommastellen hat (bzw. ungleich Null ist). Falls nein, wird 0 zurückgegeben. Sonst wird die Zahl in einen String umgewandelt und dessen Länge minus zwei zurückgegeben (-2 da die Länge das „0,” am Anfang der Zahl mit einschließt). Bei Zahlen mit sehr vielen Stellen trifft diese Funktion tendenziell eher das richtige Ergebnis, jedoch macht sich die Ungenauigkeit von Floats bemerkbar.
<?php $numbers = array(1, 1.0, 1.424000000000, 3.141, 0.123456789, 1e10, 13134.4324234, 2389.1111111111111, 99999999.2222222222); function decimalPlaces($number) { $dp = abs($number - (int)$number); return ($dp>0 ? strlen(strval($dp))-2 : 0); } foreach ($numbers as $number) { echo $number." (Nachkomma: ".($number - floor($number))."): ".decimalPlaces($number)."\n"; } ?>
1 (Nachkomma: 0): 0 1 (Nachkomma: 0): 0 1.424 (Nachkomma: 0.424): 3 3.141 (Nachkomma: 0.141): 3 0.123456789 (Nachkomma: 0.123456789): 9 10000000000 (Nachkomma: 0): 8 13134.4324234 (Nachkomma: 0.43242339999961): 14 2389.1111111111 (Nachkomma: 0.11111111111131): 14 99999999.222222 (Nachkomma: 0.22222222387791): 14