Мне нужно округлить десятичное число в PHP до двух знаков после запятой, чтобы:
49.955
становится …
49.95
Я попробовал number_format , но это просто округляет значение до 49.96 . Я не могу использовать substr, потому что число может быть меньше (например, 7.950). На данный момент я не смог найти ответ.
Любая помощь очень ценится.
Это может работать: floor($number * 100) / 100
Вот хорошая функция, которая делает трюк без использования строковых функций:
<?php function floorp($val, $precision) { $mult = pow(10, $precision); return floor($val * $mult) / $mult; } print floorp(49.955, 2); ?>
Другой вариант заключается в вычитании доли перед округлением:
function floorp($val, $precision) { $half = 0.5 / pow(10, $precision); return round($val - $half, $precision); }
Умножьте свой ввод на 100, floor (), затем разделите результат на 100.
К сожалению, ни один из предыдущих ответов (включая принятый) не работает для всех возможных входов.
1) sprintf('%1.'.$precision.'f', $val)
Сбой с точностью 2: 14.239 должен возвращать 14.23 (но в этом случае возвращает 14.24).
2) floatval(substr($val, 0, strpos($val, '.') + $precision + 1))
Сбой с точностью 0: 14 должен возвращать 14 (но в этом случае возвращает 1)
3) substr($val, 0, strrpos($val, '.', 0) + (1 + $precision))
Сбой с точностью 0: -1 должен возвращать -1 (но в этом случае возвращает '-')
4) floor($val * pow(10, $precision)) / pow(10, $precision)
Хотя я использовал этот экстенсивно, я недавно обнаружил в нем недостаток; он не подходит для некоторых значений. С точностью 2: 2.05 следует вернуть 2.05 (но в этом случае возвращает 2.04 !!)
Пока единственный способ передать все мои тесты, к сожалению, использовать манипуляции с строкой. Мое решение, основанное на рациональном бозе, – это:
function floorDec($val, $precision = 2) { if ($precision < 0) { $precision = 0; } $numPointPosition = intval(strpos($val, '.')); if ($numPointPosition === 0) { //$val is an integer return $val; } return floatval(substr($val, 0, $numPointPosition + $precision + 1)); }
Эта функция работает с положительным и отрицательным числом, а также с любой необходимой точностью.
Здесь вы можете найти рабочий пример: http://codepad.viper-7.com/ZGprQJ .
Попробуйте функцию round()
round($num, 2, PHP_ROUND_HALF_DOWN);
: round($num, 2, PHP_ROUND_HALF_DOWN);
function roundDown($decimal, $precision) { $fraction = substr($decimal - floor($decimal), 2, $precision); //calculates the decimal places to $precision length $newDecimal = floor($decimal). '.' .$fraction; // reconstructs decimal with new # of decimal places return floatval($newDecimal); } echo roundDown(345.8768378, 5); // OUTPUT: 345.87683
Эта функция работает с положительным и отрицательным числом.
Пример кода здесь: http://codepad.org/RAOyBCuY
Использовать форматированный вывод
sprintf("%1.2f",49.955) //49.95
DEMO
Вы можете использовать:
$num = 49.9555; echo substr($num, 0, strpos($num, '.') + 3);
Альтернативное решение с использованием регулярного выражения, которое должно работать для всех положительных или отрицательных чисел, целых или с десятичными знаками:
if (preg_match('/^-?(\d+\.?\d{1,2})\d*$/', $originalValue, $matches)){ $roundedValue = $matches[1]; } else { throw new \Exception('Cannot round down properly '.$originalValue.' to two decimal places'); }
Как насчет этого?
$value = 49.955; echo intval( $value * 100 ) / 100;
Вот демонстрация
sprintf("%1.2f",49.955) //49.95
если вам нужно обрезать десятичные знаки без округления – это не подходит, потому что он будет работать правильно до 49,95 5 в конце, если число больше, например 49,95 7, оно будет округлено до 49,96
Мне кажется, что ответ Lght с полом является самым универсальным.
Вы пробовали round($val,2)
?
Дополнительная информация о функции round()