# How to ceil, floor and round bcmath numbers?

After a night lost trying to solve this problem I believe I’ve found a rather simple solution, here it is:

``````function bcceil(\$number)
{
if (strpos(\$number, '.') !== false) {
if (preg_match("~\.[0]+\$~", \$number)) {
return bcround(\$number, 0);
}

if (\$number[0] != '-') {
}

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

function bcfloor(\$number)
{
if (strpos(\$number, '.') !== false) {
if (preg_match("~\.[0]+\$~", \$number)) {
return bcround(\$number, 0);
}

if (\$number[0] != '-') {
}

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

function bcround(\$number, \$precision = 0)
{
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);
}

return \$number;
}
``````

I think I didn’t miss anything, if someone can spot any bug please let me know. Here are some tests:

``````assert(bcceil('4') == ceil('4')); // true
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') == floor('4')); // 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', 0) == number_format('3', 0)); // 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
``````