Last active
December 19, 2020 20:19
-
-
Save gh640/6d65226c6203f2cb0ebe42fbddca8ece to your computer and use it in GitHub Desktop.
PHP: ceil() and floor() with precision
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?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); |
@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.
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
@malsatin Thank you for your comments. Your code looks better. I'd like to update the code but I'm busy and don't have enough time now... :( I'll come back soon. Thanks!