That function fails occasionally, e.g. when the value passed to it is 0.245 or 1.015. I think the problem is with too many floating point operations, each one potentially introducing a small error due to the inexactitude of the c fp library.
This one uses string and bcmath operations and returns correct results in my testing.
function my_round($num)
{
if (!strpos($num, '.')) {
return $num;
}
$num = '0' . $num;
$num_arr = explode('.', $num);
if (empty($num_arr[1]) || (strlen($num_arr[1]) < 3)) {
return $num;
}
$units = ltrim($num_arr[0], '0');
$cents = substr($num_arr[1], 0, 2);
$extra = rtrim(substr($num_arr[1], 2), '0');
$mils = substr($extra, 0, 1);
if (($mils < 5) || (($extra == 5) && !($cents % 2))) {
return $units . '.' . $cents;
} else {
return ltrim(bcadd(($units . '.' . $cents), '.01', 2), '0');
}
}
Edit: The line
if (!strpos($num, '.'))
should, of course, be
if (strpos($num, '.') === false)
for well-known reasons.