阿拉伯数字转中文数字(使用PHP实现)

中文数字的特点

  • 每个计数数字都跟着一个权位,权位有:十、百、千、万、亿。
  • 以“万”为小节,对应一个节权位,万以下没有节权位(例如”一千“)。
  • 每个小节内部以“十百千”为权位独立计数。
  • “十百千”不能连续出现,而“万”和“亿”作为节权位时可以和其他权位连用,如:“二十亿”。

中文数字对“零”的使用要满足以下三条规则

  • 以10000为小节,小节的结尾即使是0,也不使用零,例如”一万“、”一百万四千“。
  • 小节内两个非0数字之间要使用“零”,例如”一百零一“。
  • 当小节的“千”位是0时,只要不是首小节,都要补“零”,例如“一万零九百九十九”,”九百万零五十“。

算法设计的一些说明:

  • 对“零”的第三个规则,把检测放在循环的最前面并默认为false,可以自然的丢弃最高小节的加零判断。
  • 把“十一”开头的“十一”改为“十”

代码示例

<?php

//阿拉伯数字转中文数字
function numberToChinese(int $num)
{
    //节权位的位置
    $unit_section_pos = 0;
    $chn_str = '';
    //单个数字转换用的数组
    $chn_num_char = ["零", "一", "二", "三", "四", "五", "六", "七", "八", "九"];
    //节权位转换用的数组
    $chn_unit_section = ["", "万", "亿", "万亿", "亿亿"];
    //节内权位换算的数组
    $chn_unit_char = ["", "十", "百", "千"];
    $need_zero = false;

    if ($num === 0) {
        return $chn_num_char[0];
    }

    //节内换算的闭包
    $section_to_chinese = function ($section) use ($chn_num_char, $chn_unit_char) {
        $chn_str = '';
        //节内的位置
        $unit_pos = 0;
        $zero = true;

        while ($section > 0) {
            $v = $section % 10;
            if ($v === 0) {
                if (!$zero) {
                    $zero = true;
                    $chn_str = $chn_num_char[$v] . $chn_str;
                }
            } else {
                $zero = false;
                $str_ins = $chn_num_char[$v];
                $str_ins .= $chn_unit_char[$unit_pos];
                $chn_str = $str_ins . $chn_str;
            }
            $unit_pos++;
            $section = floor($section / 10);
        }
        return $chn_str;
    };

    while ($num > 0) {
        $section = $num % 10000;
        if ($need_zero) {
            $chn_str = $chn_num_char[0] . $chn_str;
        }
        $str_ins = $section_to_chinese($section);
        $str_ins .= ($section !== 0) ? $chn_unit_section[$unit_section_pos] : $chn_unit_section[0];
        $chn_str = $str_ins . $chn_str;
        $need_zero = ($section < 1000) && ($section > 0);
        $num = floor($num / 10000);
        $unit_section_pos++;
    }

    $search = '一十';
    $replacement = '十';
    //处理含一十开头的(这个可根据需求处理)
    if (mb_substr($chn_str, 0, 2) === $search) {
        $position = strpos($chn_str, $search);
        $chn_str = substr_replace($chn_str, $replacement, $position, strlen($search));
    }

    return $chn_str;
}

echo numberToChinese(1000001);

参考连接

https://segmentfault.com/a/1190000004881457?utm_source=sf-similar-article

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值