对长数字字符串进行四舍五入

14 篇文章 4 订阅
12 篇文章 0 订阅
/**
 * 对长数字字符串四舍五入
 * @param string $num 长数字字符串
 * @param int    $places 保留小数位数
 * @return string
 */
function sp_round(string $num, int $places): string
{
    // 检验数字字符串
    preg_match_all('/[^\d.]+/', $num, $matches);
    if ($matches[0]) die('不合法的数字字符串');

    if (!str_contains($num, '.'))
        return $num;

    $start = $end = ''; // 两个子字符串
    $is_point = false; // 是否经过小数点
    $point = 0; // 小数点后小数位数
    $len = 0; // start字符串长度

    // 拆分成两个子字符串
    for ($i = 0; isset($num[$i]); ++ $i) {
        if ($point < $places) {
            $start .= $num[$i];
            ++ $len;
        } else {
            $end .= $num[$i];
        }

        if ($num[$i] == '.') $is_point = true;
        if ($is_point) ++ $point;
        if ($point == $places + 2) break;
    }

    // 四舍五入
    $len2 = strlen($end);
    if ($len2 == 2 && $end[1] > 4) {
        if ($end[0] == 9) {
            $end[0] = 0;

            for ($i = $len - 1; $i > -1; -- $i) {
                if ($start[$i] == '.') continue;
                if ($start[$i] == 9) {
                    $start[$i] = 0;
                } else {
                    $start[$i] = intval($start[$i]) + 1;
                    break;
                }
            }

            if ($start[0] == 0) $start = '1' . $start;
        } else {
            $end[0] = intval($end[0]) + 1;
        }
    }

    if ($len2) $end = $end[0];
    return $start . $end;
}

v(sp_round('1234567897897465.123456', 3));
v(sp_round('1234567897897465.123456', 4));
v(sp_round('1234567897897465.109956', 4));
v(sp_round('9999999999999999.999956', 4));

执行结果:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值