<?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); |
This comment has been minimized.
This comment has been minimized.
@malsatin Hi. Thank you for your comment. I tested some patterns.
var_dump(floor_plus(0, 0)); # => float(-1). This should be float(0).
var_dump(floor_plus(0, 1)); # => float(-0.1). This should be float(0).
var_dump(floor_plus(1, 0)); # => float(1)
var_dump(floor_plus(1, 1)); # => float(1) I confirmed the returned values for |
This comment has been minimized.
This comment has been minimized.
@gh640 var_dump(floor_plus(0.002, 3)); // => float(0.002)
var_dump(floor_plus(0.001, 3)); // => float(0) |
This comment has been minimized.
This comment has been minimized.
Yesterday I have also make a working solution, with some help of StackOverflow tips. Now it also supports negative values rounding. ceil function ceil(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);
} ceil: function floor(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);
} |
This comment has been minimized.
This comment has been minimized.
@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! |
This comment has been minimized.
This comment has been minimized.
@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. |
This comment has been minimized.
This comment has been minimized.
Thank you too. Hopefully this thread would help someone in the future |
This comment has been minimized.
hi there. The function
floor_plus
would work incorrectly for0
and1
values