You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP数字转金额单词算法问题求助:dinars与millimes转换异常

PHP数字转金额单词算法修正

需求说明

  • 输入小于1000(如999)时,输出应为「nine hundred and ninety-nine millimes」
  • 输入大于999时,按1 dinar = 1000 millimes拆分输出:
    • 输入1590 → 「one dinar and five hundred and ninety millimes」
    • 输入275590 → 「two hundred and seventy-five dinars and five hundred and ninety millimes」

原代码问题

<?php 
function numtowords($num){ 
    $decones = array( 
                '01' => "One", 
                '02' => "Two", 
                '03' => "Three", 
                '04' => "Four", 
                '05' => "Five", 
                '06' => "Six", 
                '07' => "Seven", 
                '08' => "Eight", 
                '09' => "Nine", 
                10 => "Ten", 
                11 => "Eleven", 
                12 => "Twelve", 
                13 => "Thirteen", 
                14 => "Fourteen", 
                15 => "Fifteen", 
                16 => "Sixteen", 
                17 => "Seventeen", 
                18 => "Eighteen", 
                19 => "Nineteen" 
                );
    $ones = array( 
                0 => " ",
                1 => "One",     
                2 => "Two", 
                3 => "Three", 
                4 => "Four", 
                5 => "Five", 
                6 => "Six", 
                7 => "Seven", 
                8 => "Eight", 
                9 => "Nine", 
                10 => "Ten", 
                11 => "Eleven", 
                12 => "Twelve", 
                13 => "Thirteen", 
                14 => "Fourteen", 
                15 => "Fifteen", 
                16 => "Sixteen", 
                17 => "Seventeen", 
                18 => "Eighteen", 
                19 => "Nineteen" 
                ); 
    $tens = array( 
                0 => "",
                2 => "Twenty", 
                3 => "Thirty", 
                4 => "Forty", 
                5 => "Fifty", 
                6 => "Sixty", 
                7 => "Seventy", 
                8 => "Eighty", 
                9 => "Ninety" 
                ); 
    $hundreds = array( 
                "Hundred", 
                "Thousand", 
                "Million", 
                "Billion", 
                "Trillion", 
                "Quadrillion" 
                ); //limit t quadrillion 
    $num = number_format($num,2,".",","); 
    $num_arr = explode(".",$num); 
    $wholenum = $num_arr[0]; 
    $decnum = $num_arr[1]; 
    $whole_arr = array_reverse(explode(",",$wholenum)); 
    krsort($whole_arr); 
    $rettxt = ""; 
    foreach($whole_arr as $key => $i){ 
        if($i < 20){ 
            $rettxt .= $ones[$i]; 
        }
        elseif($i < 100){ 
            $rettxt .= $tens[substr($i,0,1)]; 
            $rettxt .= " ".$ones[substr($i,1,1)]; 
        }
        else{ 
            $rettxt .= $ones[substr($i,0,1)]." ".$hundreds[0]; 
            $rettxt .= " ".$tens[substr($i,1,1)]; 
            $rettxt .= " ".$ones[substr($i,2,1)]; 
        } 
        if($key > 0){ 
            $rettxt .= " ".$hundreds[$key]." "; 
        } 

    } 
    $rettxt = $rettxt." dinar/s";

    if($decnum > 0){ 
        $rettxt .= " and "; 
        if($decnum < 20){ 
            $rettxt .= $decones[$decnum]; 
        }
        elseif($decnum < 1000){ 
            $rettxt .= $tens[substr($decnum,0,1)]; 
            $rettxt .= " ".$ones[substr($decnum,1,1)]; 
        }
        $rettxt = $rettxt." FRANK/s"; 
    } 
    return $rettxt;
} 

echo numtowords(275,590);
?>

原代码核心问题:

  1. 传参错误:调用numtowords(275,590)传入两个参数,实际应传单个数字275590
  2. 金额拆分逻辑错误:错误用number_format转小数格式,未按1 dinar=1000 millimes拆分整数与余数
  3. 格式缺失:未处理百位与十位间的"and"、十位与个位的连字符(如ninety-nine)
  4. 复数错误:硬编码dinar/s和FRANK/s,不符合需求的dinars和millimes
  5. 大小写不匹配:数组单词首字母大写,需求输出全小写
  6. 三位数处理遗漏:millimes可能为0-999,但原代码仅处理两位数

修正后的代码

<?php
function numberToWords($num) {
    // 转为整数避免小数问题
    $num = (int)$num;
    
    // 小写单词表
    $ones = [
        '', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine',
        'ten', 'eleven', 'twelve', 'thirteen', 'fourteen', 'fifteen', 'sixteen',
        'seventeen', 'eighteen', 'nineteen'
    ];
    $tens = [
        '', '', 'twenty', 'thirty', 'forty', 'fifty', 'sixty', 'seventy', 'eighty', 'ninety'
    ];
    
    // 处理0-999转单词的通用函数
    function convertThreeDigits($n) {
        global $ones, $tens;
        $str = '';
        
        // 处理百位
        if ($n >= 100) {
            $str .= $ones[floor($n / 100)] . ' hundred';
            $n %= 100;
            if ($n > 0) {
                $str .= ' and ';
            }
        }
        
        // 处理十位和个位
        if ($n > 0) {
            if ($n < 20) {
                $str .= $ones[$n];
            } else {
                $str .= $tens[floor($n / 10)];
                $remainder = $n % 10;
                if ($remainder > 0) {
                    $str .= '-' . $ones[$remainder];
                }
            }
        }
        
        return trim($str);
    }
    
    // 拆分dinar和millimes
    $dinar = floor($num / 1000);
    $millimes = $num % 1000;
    $result = [];
    
    // 处理dinar部分
    if ($dinar > 0) {
        $dinarStr = convertThreeDigits($dinar);
        $dinarStr .= $dinar > 1 ? ' dinars' : ' dinar';
        $result[] = $dinarStr;
    }
    
    // 处理millimes部分
    $millimesStr = convertThreeDigits($millimes);
    if ($num < 1000 || $millimes > 0) {
        $millimesStr .= ' millimes';
        $result[] = $millimesStr;
    }
    
    // 用"and"连接两部分
    return implode(' and ', $result);
}

// 测试案例
echo numberToWords(999) . "\n"; // nine hundred and ninety-nine millimes
echo numberToWords(1590) . "\n"; // one dinar and five hundred and ninety millimes
echo numberToWords(275590) . "\n"; // two hundred and seventy-five dinars and five hundred and ninety millimes
?>

关键修改说明

  1. 金额拆分逻辑:通过floor($num/1000)和$num%1000拆分dinar与millimes,符合单位换算规则
  2. 通用转换函数:封装convertThreeDigits处理0-999的单词转换,自动添加"and"和连字符
  3. 复数处理:dinar数量>1时用dinars,millimes始终用复数形式
  4. 格式统一:所有单词用小写,匹配需求输出
  5. 传参修复:调用时传入单个整数,避免参数错误

内容的提问来源于stack exchange,提问作者med amine eddine khadhraoui

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 09:01:15