Правильное математическое округление дробной части на PHP

31.10.2022

Решая одну из задач по работе, с удивлением обнаружил, что для PHP нет "правильного" математического округления числа, такого как нас учили в школе.

Т.е. например есть число 10.444449, мы хотим его округлить до десятых. Если мы попробуем это сделать средствами PHP, т.е. функции round(), то результат мы получим "10.4". Однако если мы будем округлять число до десятых начиная с последней цифры нашего числа, то получим "10.5" ( девять мы округляем в большую сторону, т.е. четверка становится пятёркой, соответственно дальше пятёрка округляется в большую сторону и следующая четверка тоже становится пятёркой и т.д.).

Готовых решений для такого округления в интернете я не нашел к своему удивлению, поэтому набросал быстро рекурсивную функцию, которая проходится с последней цифры дробного числа, до нужной дробной точности при этом соблюдая правила указанные выше.

/*
* $num - Значение для округления.
* $precision - Количество десятичных знаков, до которых производится округление
*/
function mathRound($num, int $precision = 0) {

	$dotPos = strpos($num, ".");
	$numLength = strlen($num);
	
	if($dotPos !== false && (($numLength-1)-$dotPos) > $precision) {
		$fractionalLentgh = ($numLength-1)-$dotPos;
		$num = round($num, ($fractionalLentgh-1));
		$num = mathRound($num, $precision);
	}

	return $num;
}

// Пример вызовов
// Стандартное округление
echo round(123.044445, 1); // Результат - 123
echo round(123.044445, 2); // Результат - 123.04
// Округление с помощью данной функции
echo mathRound(123.044445, 1); // Результат - 123.1
echo mathRound(123.044445, 2); // Результат - 123.05

Я не стал передавать возможные флаги аналогичные функции round, поскольку не было в этом необходимости.


Возврат к списку