返回列表 发帖
本帖最后由 523066680 于 2014-9-16 08:59 编辑

稍微做了改进
use IO::Handle;
use utf8;
use Encode;
STDOUT->autoflush(1);
STDERR->autoflush(1);
binmode(STDOUT, ":encoding(gbk)");
our @unit_f = ("", "角");            #分省略,最后补上
our @part = ("", "萬", "亿");        #元省略,最后补上
our @unit = ("", "拾", "佰", "仟");  #同上
our @cnum = qw/零 壹 贰 叁 肆 伍 陆 柒 捌 玖 拾/;
foreach (
    1.01,
    900000000,
    0.0,
    7.2,
    12300100.12,
    101010101
) {
    printf &main($_) . "\n";
}
<STDIN>;
sub main {
    my $inp = shift;
    my ($str, $sect) = ("", "");
    my ($ni, $nf, $i) = ("", "", undef);
    return "零元" if ($inp == 0);
    #整数部分和小数部分
    ($ni, $nf) = split(/\./, sprintf("%.2f", $inp));
    #处理整数部分
    $i = 0;
    while ($ni ne "") {
        $ni=~s/(\d{0,4})$//;       #每四位数为一段进行截取
        $sect = &func($1, \@unit);
                                   # 如果某段大写返回为空(0000),则缩略
                                   # 例如壹亿,而不是壹亿萬
        if ($sect ne "") {
            $str = $sect . $part[$i] . $str;      
        }
        $i++;
    }
    $str .="元" if ($str ne "");
    #处理角和分
    $sect = &func($nf, \@unit_f);
    if ($sect ne "") {
        $str = $str . $sect;
        $str = $str ."分" unless ($sect=~/角$/);
    }
    return $str;
}
sub func {
    our @cnum;
    my ($num, $unit) = (shift, shift);
    my @ints = reverse( split("", $num) );  #反转成 (个,十,佰,仟)
    my $prev = 1;
    my $begin = 0;
    my $i;
    my $str = "";
    #略过低位连续出现的零
    #例如,一百零拾零元简写为:一百元
    while (
        defined $ints[$begin]
            and
        $ints[$begin] == 0
    ) {
        $begin++;
    }
    foreach $i ($begin .. $#ints) {
        if (
            $ints[$i] == 0
        ) {
            if ($prev != 0) {
                $str = $cnum[$ints[$i]] . $str;   #零
                $prev = 0;
            }
            next;
        }
        $prev = $ints[$i];
        $str = $cnum[$ints[$i]] . $unit->[$i] . $str;
    }
    return $str;
}COPY
[url=][/url]

TOP

返回列表