How to ceil, floor and round bcmath numbers?

前端 未结 5 1889
梦如初夏
梦如初夏 2020-11-29 08:42

I need to mimic the exact functionality of the ceil(), floor() and round() functions on bcmath numbers, I\'ve already found a very similar question but unfo

5条回答
  •  青春惊慌失措
    2020-11-29 09:04

    Here's ones that support negative numbers and precision argument for rounding.

    function bcceil($val) {
        if (($pos = strpos($val, '.')) !== false) {
            if ($val[$pos+1] != 0 && $val[0] != '-')
                return bcadd(substr($val, 0, $pos), 1, 0);
            else
                return substr($val, 0, $pos);
        }
        return $val;
    }
    
    function bcfloor($val) {
        if (($pos = strpos($val, '.')) !== false) {
            if ($val[$pos+1] != 0 && $val[0] == '-')
                return bcsub(substr($val, 0, $pos), 1, 0);
            else
                return substr($val, 0, $pos);
        }
        return $val;
    }
    
    function bcround($val, $precision = 0) {
        if (($pos = strpos($val, '.')) !== false) {
            if ($precision > 0) {
                $int = substr($val, 0, $pos);
                $pos2 = ++$pos+$precision;
                if ($pos2 < strlen($val)) {
                    $val2 = sprintf('%s.%s', substr($val, $pos, $pos2-$pos), substr($val, $pos2));
                    $val2 = $val2[0] >= 5 ? bcceil($val2) : bcfloor($val2);
                    if (strlen($val2) > $precision)
                        return bcadd($int, $val[0] == '-' ? -1 : 1, 0);
                    else
                        return sprintf('%s.%s', $int, rtrim($val2, '0'));
                }
                return $val;
            } else {
                if ($val[$pos+1] >= 5)
                    return ($val[0] == '-' ? bcfloor($val) : bcceil($val));
                else
                    return ($val[0] == '-' ? bcceil($val) : bcfloor($val));
            }
        }
        return $val;
    }
    

提交回复
热议问题