Skip to content

Instantly share code, notes, and snippets.

@gh640
Last active December 19, 2020 20:19
Embed
What would you like to do?
PHP: ceil() and floor() with precision
<?php
function ceil_plus(float $value, ?int $precision = null): float
{
if (null === $precision) {
return (float) ceil($value);
}
if ($precision < 0) {
throw new \RuntimeException('Invalid precision');
}
$reg = $value + 0.5 / (10 ** $precision);
return round($reg, $precision, $reg > 0 ? PHP_ROUND_HALF_DOWN : PHP_ROUND_HALF_UP);
}
function floor_plus(float $value, ?int $precision = null): float
{
if (null === $precision) {
return (float)floor($value);
}
if ($precision < 0) {
throw new \RuntimeException('Invalid precision');
}
$reg = $value - 0.5 / (10 ** $precision);
return round($reg, $precision, $reg > 0 ? PHP_ROUND_HALF_UP : PHP_ROUND_HALF_DOWN);
}
// Tests for ceil_plus().
assert(ceil_plus(3.14, 0) === 4.0);
assert(ceil_plus(3.14, 1) === 3.2);
assert(ceil_plus(3.14, 2) === 3.14);
assert(ceil_plus(3.1415, 0) === 4.0);
assert(ceil_plus(3.1415, 1) === 3.2);
assert(ceil_plus(3.1415, 2) === 3.15);
assert(ceil_plus(3.1415, 3) === 3.142);
assert(ceil_plus(3.1415, 4) === 3.1415);
assert(ceil_plus(0.002, 3) === 0.002);
assert(ceil_plus(0.0015, 3) === 0.002);
assert(ceil_plus(0.001, 3) === 0.001);
assert(ceil_plus(0, 0) === 0.0);
assert(ceil_plus(-0.001, 3) === -0.001);
assert(ceil_plus(-0.0015, 3) === -0.001);
assert(ceil_plus(-0.002, 3) === -0.002);
assert(ceil_plus(-1, 0) === -1.0);
// Tests for floor_plus().
assert(floor_plus(3.14, 0) === 3.0);
assert(floor_plus(3.14, 1) === 3.1);
assert(floor_plus(3.14, 2) === 3.14);
assert(floor_plus(3.1415, 0) === 3.0);
assert(floor_plus(3.1415, 1) === 3.1);
assert(floor_plus(3.1415, 2) === 3.14);
assert(floor_plus(3.1415, 3) === 3.141);
assert(floor_plus(3.1415, 4) === 3.1415);
assert(floor_plus(0.002, 3) === 0.002);
assert(floor_plus(0.0015, 3) === 0.001);
assert(floor_plus(0.001, 3) === 0.001);
assert(floor_plus(0, 0) === 0.0);
assert(floor_plus(-0.001, 3) === -0.001);
assert(floor_plus(-0.0015, 3) === -0.002);
assert(floor_plus(-0.002, 3) === -0.002);
assert(floor_plus(-1, 0) === -1.0);
@gh640
Copy link
Author

gh640 commented Dec 19, 2020

@malsatin Sorry for my slow reaction. I tested some cases with you implementation and they look fine! I've updated the code above with some additional assertions. Thank you.

@malsatin
Copy link

Thank you too. Hopefully this thread would help someone in the future

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment