How to round/ceil/floor a bcmath number in PHP?

php round
php round to nearest 5
php round down
php multiply large numbers
php-bcmath
php ceil
php round up
php round even

Is there any library function for this purpose, so I don't do it by hand and risk ending in TDWTF?

echo ceil(31497230840470473074370324734723042.6);

// Expected result
31497230840470473074370324734723043

// Prints
<garbage>

This will work for you:

$x = '31497230840470473074370324734723042.9';

bcscale(100);
var_dump(bcFloor($x));
var_dump(bcCeil($x));
var_dump(bcRound($x));

function bcFloor($x)
{
    $result = bcmul($x, '1', 0);
    if ((bccomp($result, '0', 0) == -1) && bccomp($x, $result, 1))
        $result = bcsub($result, 1, 0);

    return $result;
}

function bcCeil($x)
{
    $floor = bcFloor($x);
    return bcadd($floor, ceil(bcsub($x, $floor)), 0);
}

function bcRound($x)
{
    $floor = bcFloor($x);
    return bcadd($floor, round(bcsub($x, $floor)), 0);
}

Basically it finds the flooy by multiplying by one with zero precision.

Then it can do ceil / round by subtracting that from the total, calling the built in functions, then adding the result back on

Edit: fixed for -ve numbers

How to round/ceil/floor a bcmath number in PHP?, This will work for you: $x = '31497230840470473074370324734723042.9'; bcscale(100); var_dump(bcFloor($x)); var_dump(bcCeil($x));� The ceil() function rounds a number UP to the nearest integer, if necessary. Tip: To round a number DOWN to the nearest integer, look at the floor() function. Tip: To round a floating-point number, look at the round() function.

UPDATE: See my improved answer here: How to ceil, floor and round bcmath numbers?.


These functions seem to make more sense, at least to me:

function bcceil($number)
{
    if ($number[0] != '-')
    {
        return bcadd($number, 1, 0);
    }

    return bcsub($number, 0, 0);
}

function bcfloor($number)
{
    if ($number[0] != '-')
    {
        return bcadd($number, 0, 0);
    }

    return bcsub($number, 1, 0);
}

function bcround($number, $precision = 0)
{
    if ($number[0] != '-')
    {
        return bcadd($number, '0.' . str_repeat('0', $precision) . '5', $precision);
    }

    return bcsub($number, '0.' . str_repeat('0', $precision) . '5', $precision);
}

They support negative numbers and the precision argument for the bcround() function.

Some tests:

assert(bcceil('4.3') == ceil('4.3')); // true
assert(bcceil('9.999') == ceil('9.999')); // true
assert(bcceil('-3.14') == ceil('-3.14')); // true

assert(bcfloor('4.3') == floor('4.3')); // true
assert(bcfloor('9.999') == floor('9.999')); // true
assert(bcfloor('-3.14') == floor('-3.14')); // true

assert(bcround('3.4', 0) == number_format('3.4', 0)); // true
assert(bcround('3.5', 0) == number_format('3.5', 0)); // true
assert(bcround('3.6', 0) == number_format('3.6', 0)); // true
assert(bcround('1.95583', 2) == number_format('1.95583', 2)); // true
assert(bcround('5.045', 2) == number_format('5.045', 2)); // true
assert(bcround('5.055', 2) == number_format('5.055', 2)); // true
assert(bcround('9.999', 2) == number_format('9.999', 2)); // true

BC Math Functions - Manual, rounds up a float to a specified number of decimal places // (basically acts like ceil() but allows for decimal places) function round_up ($value, $places=0) { Basically it finds the flooy by multiplying by one with zero precision. Then it can do ceil / round by subtracting that from the total, calling the built in functions, then adding the result back on Edit: fixed for -ve numbers

OK, for my high-precision Money library, which is currently on hundreds of production sites, I had to completely rewrite this bcround functionality. Nothing I found on the entire Internet was up to code.

Here's what I came up with:

/**
 * Based off of https://stackoverflow.com/a/1653826/430062
 * Thanks, [Alix Axel](https://stackoverflow.com/users/89771/alix-axel)!
 *
 * @param $number
 * @param int $precision
 * @return string
 */
function bcround($number, $precision = BCMathCalcStrategy::PRECISION)
{
    if (strpos($number, '.') !== false) {
        if ($number[0] != '-') return bcadd($number, '0.' . str_repeat('0', $precision) . '5', $precision);
        return bcsub($number, '0.' . str_repeat('0', $precision) . '5', $precision);
    }

    // Pad it out to the desired precision.
    return number_format($number, $precision);
}

ceil - Manual, Is there any library function for this purpose, so I don't do it by hand and risk ending in TDWTF? echo ceil(31497230840470473074370324734723042.6);� float round (float value [, int precision ]) It is a common situation that you want less accuracy than PHP gives you, in which case you need to use one of PHP's selection of rounding functions: ceil (), floor (), and round (). Both ceil () and floor () take just one parameter - the number to round.

How to round/ceil/floor a bcmath number in PHP?, Extends php BCMath lib for missing functions like floor, ceil, round, abs, min, max , rand for big numbers. Also wraps existing BCMath functions. puis il peut faire ceil / round en soustrayant cela du total, en appelant les fonctions intégrées, puis en ajoutant le résultat de nouveau sur Edit: fixe pour cinq numéros de 7

krowinski/bcmath-extended: Extends php BCMath lib for , The current goto answer for arbitrary precision math in PHP is bcmath. Precision is defined as the number of significant figures, and scale is the number @return Decimal */ function factorial(int $n, int $p = Decimal:: DEFAULT_PRECISION):� Specifies the number of decimal digits to round to. Default is 0: mode: Optional. Specifies a constant to specify the rounding mode: PHP_ROUND_HALF_UP - Default. Rounds number up to precision decimal, when it is half way there. Rounds 1.5 to 2 and -1.5 to -2; PHP_ROUND_HALF_DOWN - Round number down to precision decimal places, when it is half

PHP Decimal, Both ceil() and floor() take just one parameter - the number to round. Ceil() takes the number and rounds it to the nearest integer above its current value,� Extends php BCMath lib for missing functions like floor, ceil, round, abs, min, max, rand for big numbers. Also wraps existing BCMath functions. bignumber math php arbitrary-precision complex-numbers decimals money ceil floor abs rand scientific-notation deche composer-packages

Comments
  • See also my related question: stackoverflow.com/questions/1642614/…
  • +1, but it might be worth adding a scale argument to bcCeil and bcRound, as the behaviour is dependent on the scale. If you call bcscale(0) then try bcCeil('1.1') you're going to get '1' not '2' as you might expect. Allowing the scale to be specified would be consistent with the other BCMath functions.
  • Also to note, the scale argument should be default null and should not overwrite the value set by bcscale if not provided.
  • Won't work with integers. Good realisation of these functions here: stackoverflow.com/a/1653826/541961 Alix, you can edit your post to link to the newer one.
  • @Dmitriy: Done. Thanks.