1. Einleitung
PHP bietet drei Funktionen zum Runden von Zahlen an:
- round($number, $precision, $mode): Das „normale” Runden. Zahlen kleiner x,5 werden abgerundet, Zahlen größer x,5 aufgerundet. Das Verhalten für exakt x,5 (aufrunden oder abrunden) lässt sich über $mode festlegen. Über $precision wiederum kann die Präzision festgelegt werden, also die Anzahl der Nachkommastellen. Ein Wert von 2 für $precision würde die Zahl so runden, dass zwei Nachkommastellen übrig bleiben.
- ceil($number): Alle Werte größer x,0 werden aufgerundet. (Werte kleiner als 0,5 werden also nicht abgerundet.) Eine Präzision wie bei round() lässt sich nicht festlegen.
- floor($number): Alle Werte größer x,0 werden abgerundet. (Werte größer als 0,5 werden also nicht aufgerundet.) Eine Präzision wie bei round() lässt sich nicht festlegen.
2. Float auf- und abrunden
Nachfolgend wird round() beispielhaft vorgeführt. Es wird kein $precision-Parameter übergeben, sodass auf eine ganze Zahl hin gerundet wird.
<?php $n1 = 1.2; $n2 = 3.0; $n3 = 18.41452; $n4 = 1.5; var_dump(round($n1), round($n2), round($n3), round($n4)); ?>
float(1) float(3) float(18) float(2)
Diesmal wird ein Wert für den $precision-Parameter von round() übergeben, sodass auf eine bestimmte Zahl von Nachkommastellen hin gerundet wird (nacheinander auf null, eine und zwei Nachkommastellen):
<?php $n = 1.1234567; var_dump(round($n, 0), round($n, 1), round($n, 2)); ?>
float(1) float(1.1) float(1.12)
round() stellt vier Flags zur Verfügung, die als dritter Parameter übergeben werden können:
- PHP_ROUND_HALF_UP: bei exakt x,5 wird aufgerundet (Standardverhalten)
- PHP_ROUND_HALF_DOWN: bei exakt x,5 wird abgerundet
- PHP_ROUND_HALF_EVEN: bei exakt x,5 wird zur nächsten geraden Zahl hin gerundet (bei ungeraden Zahlen also aufgerundet)
- PHP_ROUND_HALF_ODD: bei exakt x,5 wird zur nächsten ungeraden Zahl hin gerundet (bei geraden Zahlen also aufgerundet)
<?php $n100_5 = 100.5; $n101_5 = 101.5; var_dump(round($n100_5, 0, PHP_ROUND_HALF_UP)); // 101 var_dump(round($n100_5, 0, PHP_ROUND_HALF_DOWN)); // 100 var_dump(round($n100_5, 0, PHP_ROUND_HALF_EVEN)); // 100 var_dump(round($n101_5, 0, PHP_ROUND_HALF_EVEN)); // 102 var_dump(round($n100_5, 0, PHP_ROUND_HALF_ODD)); // 101 var_dump(round($n101_5, 0, PHP_ROUND_HALF_ODD)); // 101 ?>
float(101) float(100) float(100) float(102) float(101) float(101)
3. Float aufrunden
Mit ceil() kann eine Zahl aufgerundet werden. Im nächsten Beispiel wird diese Funktion gezeigt, im Vergleich mit round():
<?php $n = 1.345; // runden auf 0 Nachkommastellen var_dump(round($n, 0, PHP_ROUND_HALF_UP)); // 1 var_dump(ceil($n)); // 2 // runden auf eine Nachkommastelle, benoetigt bei ceil() zusaetzliche Berechnungen var_dump(round($n, 1, PHP_ROUND_HALF_UP)); // 1.3 var_dump(ceil($n*10)/10); // 1.4 ?>
float(1) float(2) float(1.3) float(1.4)
4. ceil() mit Präzision (Anzahl der Nachkommastellen als Parameter)
Standardmäßig verfügt ceil() nicht — wie round() — über einen Parameter zur Bestimmung der Anzahl der Nachkommastellen auf die gerundet werden soll. Dieser lässt sich aber in einer eigenen Funktion leicht nachbilden. Soll $x auf $n Nachkommastellen gerundet werden, dann muss man (ceil($x / 10$n))*10$n rechnen:
<?php function ceilPrecision($value, $precision = 0) { return ceil($value * pow(10, $precision)) / pow(10, $precision); } var_dump(ceilPrecision(0, 0)); // 0 var_dump(ceilPrecision(0.1, 0)); // 1 var_dump(ceilPrecision(0.11, 1)); // 0.2 var_dump(ceilPrecision(0.111, 2)); // 0.12 var_dump(ceilPrecision(0.1, 9)); // 0.1 var_dump(ceilPrecision(1741, -2)); // 1800 ?>
float(0) float(1) float(0.2) float(0.12) float(0.1) float(1800)
5. Float abrunden
Analog zu ceil() kann floor() verwendet werden, um eine Zahl abzurunden. Das Verhalten der Funktion wird nachfolgend wieder im Vergleich mit round() gezeigt:
<?php $n = 1.789; // runden auf 0 Nachkommastellen var_dump(round($n, 0, PHP_ROUND_HALF_DOWN)); // 2 var_dump(floor($n)); // 1 // runden auf eine Nachkommastelle, benoetigt auch bei floor() zusaetzliche Berechnungen var_dump(round($n, 1, PHP_ROUND_HALF_DOWN)); // 1.8 var_dump(floor($n*10)/10); // 1.7 ?>
float(2) float(1) float(1.8) float(1.7)
6. floor() mit Präzision (Anzahl der Nachkommastellen als Parameter)
Genauso wie bei ceil() kann auch für floor() eine Funktion definiert werden, um die Anzahl der Nachkommastellen festlegen zu können:
<?php function floorPrecision($value, $precision = 0) { return floor($value * pow(10, $precision)) / pow(10, $precision); } var_dump(floorPrecision(0, 0)); // 0 var_dump(floorPrecision(0.1, 0)); // 0 var_dump(floorPrecision(0.77, 1)); // 0.7 var_dump(floorPrecision(0.777, 2)); // 0.77 var_dump(floorPrecision(0.7, 9)); // 0.7 var_dump(floorPrecision(1741, -2)); // 1700 ?>
float(0) float(0) float(0.7) float(0.77) float(0.7) float(1700)
7. Eigene Funktion zum Runden
Nachfolgend wird beispielhaft dargestellt, wie eine eigene Funktion zum Runden von Zahlen (ähnlich zu round()) implementiert werden könnte. Die Funktion „myRound($n, $p)” geht wie folgt für eine Zahl $n vor:
- Die Zahl wird mit 10p multipliziert, wobei p die Präzision (Anzahl der Nachkommastellen) ist.
- Es wird ermittelt, welcher Rest „m” übrig bleiben würde, falls man die Zahl durch 10 teilen würde.
- Alle Nachkommastellen der Zahl werden abgeschnitten (nachdem die Multiplikation mit 10p durchgeführt wurde).
- Falls „m” exakt 5 oder größer als 5 (6-9) ist, wird die Zahl um eins erhöht (ergibt Aufrunden von Werten der Art x,5 oder x,6 oder x,7 usw.).
- Zuletzt wird durch 10p geteilt.
<?php function myRound($value, $precision) { $value = $value * pow(10, $precision); $mod = ($value*10) % 10; $value = (int)$value; if ($mod >= 5) { $value++; } return $value / pow(10, $precision); } var_dump(myRound(0, 0)); // 0 var_dump(myRound(0.1, 0)); // 0 var_dump(myRound(0.1, 1)); // 0.1 var_dump(myRound(0.5, 0)); // 1 var_dump(myRound(0.6, 0)); // 1 var_dump(myRound(0.999, 2)); // 1 var_dump(myRound(128.759042, 2)); // 128.76 var_dump(myRound(1111, -2)); // 1100 ?>
int(0) int(0) float(0.1) int(1) int(1) int(1) float(128.76) float(1100)
8. Floats zu bestimmten Werten hin auf-/abrunden
In diesem Beispiel werden drei Funktionen vorgestellt, die die übergebene Zahl zu bestimmten Vielfachen hin runden. Dabei ist wieder sowohl das normale Runden (round()), das Aufrunden (ceil()) und das Abrunden (floor()) verfügbar. Ein Vielfaches könnte beispielsweise 0,5 sein, sodass bei Verwendung ersterer Funktion (wie round()) etwa die Zahl 0,1 zu 0,0 wird, die Zahl 0,3 jedoch zu 0,5 und 0,9 wiederum zu 1,0. Nachfolgend wird zu Vielfachen von 0,25 hin gerundet:
<?php // rundet zu bestimmten Werten hin function roundTo($float, $blockSize) { $count = 1 / $blockSize; return (round($float * $count) / $count); } // rundet zu bestimmten Werten hin AUF function ceilTo($float, $blockSize) { $count = 1 / $blockSize; return (ceil($float * $count) / $count); } // rundet zu bestimmten Werten hin AB function floorTo($float, $blockSize) { $count = 1 / $blockSize; return (floor($float * $count) / $count); } echo("roundTo:\n"); var_dump(roundTo(0, 0.25)); // 0 var_dump(roundTo(0.0001, 0.25)); // 0 var_dump(roundTo(1.1111, 0.25)); // 1 var_dump(roundTo(1.25, 0.25)); // 1.25 var_dump(roundTo(1.26, 0.25)); // 1.25 echo("\n\nceilTo:\n"); var_dump(ceilTo(0, 0.25)); // 0 var_dump(ceilTo(0.0001, 0.25)); // 0.25 var_dump(ceilTo(1.1111, 0.25)); // 1.25 var_dump(ceilTo(1.25, 0.25)); // 1.25 var_dump(ceilTo(1.26, 0.25)); // 1.5 echo("\n\nfloorTo:\n"); var_dump(floorTo(0, 0.25)); // 0 var_dump(floorTo(0.0001, 0.25)); // 0 var_dump(floorTo(1.1111, 0.25)); // 1 var_dump(floorTo(1.25, 0.25)); // 1.25 var_dump(floorTo(1.26, 0.25)); // 1.25 ?>
roundTo: float(0) float(0) float(1) float(1.25) float(1.25) ceilTo: float(0) float(0.25) float(1.25) float(1.25) float(1.5) floorTo: float(0) float(0) float(1) float(1.25) float(1.25)
9. Uhrzeit auf-/abrunden
Die Rundungsfunktionen können verwendet werden, um zu bestimmten Uhrzeiten hin zu runden (etwa zur nächsten Viertelstunde hin). Das Verfahren ist ähnlich wie im vorherigen Beispiel (das Runden zu Vielfachen einer Zahl hin), da die Uhrzeit einfach in Sekunden seit 01.01.1970 umgerechnet werden kann. Im Beispiel verwendet die Funktion „roundToMinutes()” wiederum round(), um zu einem Vielfachen einer bestimmten Minute hin zu runden. Beispielsweise könnte 10 übergeben werden, um zu Vielfachen von 10 hin zu runden, also z. B. zu 17:00, 17:10, 17:20 usw.
<?php function roundToMinutes($timeInSeconds, $minutes) { return round($timeInSeconds / ($minutes * 60)) * ($minutes * 60); } $time1 = strtotime('15:23'); $time2 = strtotime('16:00'); $time3 = strtotime('16:59:59'); $time4 = strtotime('17:01'); // Runden zur Viertelstunde hin var_dump(date('H:i:s', roundToMinutes($time1, 15))); var_dump(date('H:i:s', roundToMinutes($time2, 15))); var_dump(date('H:i:s', roundToMinutes($time3, 15))); var_dump(date('H:i:s', roundToMinutes($time4, 15))); ?>
string(8) "15:30:00" string(8) "16:00:00" string(8) "17:00:00" string(8) "17:00:00"