PHP округление чисел - PullRequest
       17

PHP округление чисел

2 голосов
/ 15 января 2010

Я не могу понять, как всегда округляться в PHP. ceil() был бы очевидным выбором, но мне нужна та же функциональность, которую round() предоставляет со вторым параметром «точность». Вот пример:

// Desired result: 6250
echo round(6244.64, -2); // returns 6200
echo round(6244.64, -1); // returns 6240
echo ceil(6244.64) // returns 6245

Мне нужно, чтобы число всегда округлялось, чтобы можно было рассчитать равный делитель на основе параметров диаграммы.

Ответы [ 6 ]

5 голосов
/ 15 января 2010

Из комментария к http://php.net/manual/en/function.ceil.php:

Quick and dirty `ceil` type function with precision capability.

function ceiling($value, $precision = 0) {
    return ceil($value * pow(10, $precision)) / pow(10, $precision);
}
1 голос
/ 22 февраля 2018

Некоторые из этих ответов имеют проблемы с арифметикой с плавающей запятой, которые могут не работать, как показано в этом ответе . Для пуленепробиваемого решения во всех случаях используйте это:

/**
 * Used to round up based on the decimal place, for example rounding up to the nearest penny
 * http://stackoverflow.com/questions/8239600/rounding-up-to-the-second-decimal-place
 * @param float $value
 * @param integer $precision
 * @return number
 */
public function Ceiling($value, $precision = 0) {
    $offset = 0.5;
    if ($precision !== 0)
        $offset /= pow(10, $precision);
    $final = round($value + $offset, $precision, PHP_ROUND_HALF_DOWN);
    return ($final == -0 ? 0 : $final);
}

/**
 * Used to round up based on the decimal place, for example rounding up to the nearest penny
 * http://stackoverflow.com/questions/8239600/rounding-up-to-the-second-decimal-place
 * @param float $value
 * @param integer $precision
 * @return number
 */
public function Floor($value, $precision = 0) {
    $offset = -0.5;
    if ($precision !== 0)
        $offset /= pow(10, $precision);
    $final = round($value + $offset, $precision, PHP_ROUND_HALF_UP);
    return ($final == -0 ? 0 : $final);
}
0 голосов
/ 26 января 2018

Поскольку версия ceil(pow(10, $precision) * $value) / pow(10, $precision); в некоторых случаях дает сбой, например, round_up (2.22, 2) выдает неверный 2.23, как указано здесь , поэтому я адаптировал это string решение для round_down () к нашей проблеме round_up (). Это результат (отрицательная точность не учитывается):

function round_up($value, $precision) {        
    $value = (float)$value;
    $precision = (int)$precision;
    if ($precision < 0) { 
        $precision = 0;
    }
    $decPointPosition = strpos($value, '.');
    if ($decPointPosition === false) { 
        return $value;
    }
    $floorValue = (float)substr($value, 0, $decPointPosition + $precision + 1);
    $followingDecimals = (int)substr($value, $decPointPosition + $precision + 1);
    if ($followingDecimals) {
        $ceilValue = $floorValue + pow(10, -$precision); // does this give always right result?
    }
    else {
        $ceilValue = $floorValue;
    }
    return $ceilValue;                
}

Я не знаю, что это пуленепробиваемый, но, по крайней мере, он удаляет вышеупомянутый сбой. Я не делал никакого двоичного к десятичному математическому анализу, но если $floorValue + pow(10, 0 - $precision) работает всегда, как и ожидалось, тогда все должно быть в порядке. Если вы обнаружите какой-то случай с ошибкой, дайте мне знать - мы должны найти другое решение:)

0 голосов
/ 02 февраля 2016

Еще одно решение для ceil с точностью, без пау, похоже, работает 9 цифр в обе стороны:

$v = 123400100100100101;
$a1 = 444444444.4;
$a2 = .04444444444;
$b1 = 111111111.1;
$b2 = .01111111111;
echo $v . "\n";
for ($i = 0; $i < 18; $i ++) {
    $v = $v/10;
    for ($j = -9; $j < 10; $j++) {
        echo $i . ':' . $j . ":" . round($v
            + round($a1, $j + 1) + round($a2, $j + 1)
            - round($a1, $j) - round($a2, $j)
            + round($b1, $j + 1) + round($b2, $j + 1)
            - round($b1, $j) - round ($b2, $j),
            $j, PHP_ROUND_HALF_DOWN) . "\n";
    }
}
0 голосов
/ 15 января 2010
echo 10*ceil($number/10);
0 голосов
/ 15 января 2010

Вы можете разделить на 10, ceil (); а затем умножить на десять

...