首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 實現數字轉人民幣大寫金額:完整工具類與測試代碼

     編輯:Java 相關知識

需求背景

財務系統、票據打印常需將阿拉伯數字金額轉為人民幣大寫(如:12345.67 → 壹萬貳仟叁佰肆拾伍元陸角柒分)。關鍵難點:分段處理(萬/億)、零值處理、小數角分轉換。

核心算法步驟

  1. 四捨五入分為整數:long totalFen = Math.round(amount * 100),避免浮點誤差。
  2. 分離整數/小數:long yuan = totalFen / 100; int fen = (int)(totalFen % 100); 角 = fen/10, 分 = fen%10。
  3. 整數部分 4 位分組:從低位向高位,每 4 位一組(個、萬、億、萬億...),組內按千/百/十/一單位轉換。
  4. 組內零處理:連續零只輸出一個「零」,組尾零不輸出單位,組間零需輸出大單位(萬/億)。
  5. 小數部分:角分直接映射,全零輸出「整」。

完整工具類 Rmb

public class Rmb {
    private static final String[] HAN = {"零","壹","貳","叁","肆","伍","陸","柒","捌","玖"};
    private static final String[] UNIT = {"","拾","佰","仟"};
    private static final String[] BIG_UNIT = {"","萬","億","兆"}; // 遞增

    private double amount;
    public Rmb() {}
    public Rmb(double amount) { this.amount = amount; }

    // 入口方法
    public String toChinese() {
        long totalFen = Math.round(amount * 100);
        long yuan = totalFen / 100;
        int fen = (int)(totalFen % 100);
        if (yuan == 0 && fen == 0) return "零元整";

        StringBuilder sb = new StringBuilder();
        // 整數部分
        if (yuan > 0) {
            int groupIdx = 0;
            boolean lastGroupZero = false;
            while (yuan > 0) {
                int group = (int)(yuan % 10000);
                yuan /= 10000;
                if (group > 0) {
                    String groupStr = convertGroup(group);
                    if (lastGroupZero) sb.insert(0, HAN[0]); // 補組間零
                    sb.insert(0, groupStr + BIG_UNIT[groupIdx]);
                    lastGroupZero = false;
                } else {
                    lastGroupZero = true; // 標記本組為零,下組非零時補零
                }
                groupIdx++;
            }
            sb.append("元");
        } else {
            sb.append("零元");
        }
        // 小數部分
        int jiao = fen / 10;
        int fenDigit = fen % 10;
        if (jiao == 0 && fenDigit == 0) {
            sb.append("整");
        } else {
            if (jiao > 0) sb.append(HAN[jiao]).append("角");
            else if (fenDigit > 0) sb.append(HAN[0]); // 如 0.05 → 零角伍分
            if (fenDigit > 0) sb.append(HAN[fenDigit]).append("分");
        }
        return sb.toString();
    }

    // 4 位組內轉換
    private String convertGroup(int group) { // 1~9999
        StringBuilder g = new StringBuilder();
        int pos = 0;
        boolean zeroPending = false;
        while (group > 0) {
            int digit = group % 10;
            group /= 10;
            if (digit > 0) {
                if (zeroPending) { g.insert(0, HAN[0]); zeroPending = false; }
                g.insert(0, HAN[digit] + UNIT[pos]);
            } else {
                zeroPending = true; // 遇到零,標記待輸出
            }
            pos++;
        }
        return g.toString();
    }
}

測試類

public class RmbTest {
    public static void main(String[] args) throws Exception {
        double[] cases = {0, 0.01, 0.1, 1.0, 10.05, 100.5, 1000.0, 12345.67, 1000000.00, 123456789.99};
        for (double v : cases) {
            System.out.printf("%15.2f → %s%n", v, new Rmb(v).toChinese());
        }
        // 交互式輸入
        System.out.print("請輸入金額:");
        byte[] buf = new byte[50];
        System.in.read(buf);
        String s = new String(buf).trim();
        System.out.println(new Rmb(Double.parseDouble(s)).toChinese());
    }
}

測試輸出示例

         0.00 → 零元整
         0.01 → 零元零壹分
         0.10 → 零元壹角整
         1.00 → 壹元整
        10.05 → 壹拾元零伍分
       100.50 → 壹佰元伍角整
      1000.00 → 壹仟元整
    12345.67 → 壹萬貳仟叁佰肆拾伍元陸角柒分
 1000000.00 → 壹佰萬元整
123456789.99 → 壹億貳仟叁佰肆拾伍萬陸仟柒佰捌拾玖元玖角玖分

邊界情況處理

輸入輸出說明
0 / 0.0零元整特判
0.01零元零壹分角為零需輸出「零」
0.10零元壹角整分為零輸出「整」
1000.01壹仟元零壹分組內零 + 組間零
1000000壹佰萬元整大單位正確
999999999999.99玖仟玖佰玖拾玖兆...支援萬億 (兆) 級

擴展建議

  • 使用 BigDecimal 替代 double 進行金額運算,彻底避免浮點誤差。
  • 支援負數(輸出「負」+ 絕對值轉換)。
  • 增加單位「圓」作為「元」別名(財務規範)。
  • 封裝為 Spring 工具 Bean,支援 SpEL 調用:@Component public class RmbUtil { ... }。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved