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

Java 浮點數轉人民幣大寫:完整實現與邊界處理指南

     編輯:Java 程式設計入門

財務系統中將數字金額轉為人民幣大寫(壹貳叁...)是剛需。本文提供一個健壯的實現,覆蓋負數、零值、大數值、小數位精度、連續零壓縮等全場景。

核心設計思路

  1. 分離整數/小數部分:long 存整數,Math.round((x - 整數)*100) 取分/角
  2. 逆序處理:從個位向高位遍歷,配合單位陣列(元、拾、佰、仟、萬、億...)
  3. 零值壓縮規則:連續零合併為單「零」;「零元/零萬/零億」修正為「元/萬/億」;「億萬」修正為「億」
  4. 小數處理:角、分非零才輸出,零則省略

完整代碼實現

import java.util.ArrayList;
import java.util.List;

public class RMBConverter {
    private static final String[] NUM = {"零","壹","貳","叁","肆","伍","陸","柒","捌","玖"};
    private static final String[] UNIT_INT = {"元","拾","佰","仟","萬","拾","佰","仟","億","拾","佰","仟","萬","拾","佰","仟"};
    private static final String[] UNIT_DEC = {"分","角"}; // 逆序:分、角

    public String convert(double amount) {
        if (amount == 0) return "零元整";

        StringBuilder sb = new StringBuilder();
        if (amount < 0) {
            sb.append("負");
            amount = -amount;
        }

        long integerPart = (long) amount;
        int decimalPart = (int) Math.round((amount - integerPart) * 100); // 四捨五入取分

        // 整數部分逆序字符數組
        char[] intDigits = String.valueOf(integerPart).toCharArray();
        List intParts = new ArrayList<>();

        for (int i = 0; i < intDigits.length; i++) {
            int digit = intDigits[intDigits.length - 1 - i] - '0'; // 從個位開始
            if (digit == 0) {
                // 萬/億位必須顯示單位,其他位僅標記零
                if (i == 4 || i == 8 || i == 0) {
                    intParts.add(NUM[0] + UNIT_INT[i]);
                } else {
                    intParts.add(NUM[0]);
                }
            } else {
                intParts.add(NUM[digit] + UNIT_INT[i]);
            }
        }

        // 逆序拼裝整數部分
        for (int i = intParts.size() - 1; i >= 0; i--) {
            sb.append(intParts.get(i));
        }

        // 小數部分
        char[] decDigits = String.valueOf(decimalPart).toCharArray();
        for (int i = 0; i < decDigits.length; i++) {
            int digit = decDigits[decDigits.length - 1 - i] - '0'; // 從分位開始
            if (digit > 0) {
                sb.append(NUM[digit]).append(UNIT_DEC[i]);
            }
        }

        // 後處理:零值壓縮與修正
        String result = sb.toString()
                .replaceAll("零+", "零")           // 連續零合併
                .replaceAll("零元", "元")
                .replaceAll("零萬", "萬")
                .replaceAll("零億", "億")
                .replaceAll("億萬", "億");         // 億萬 → 億

        // 結尾處理
        if (result.endsWith("元")) result += "整";
        if (result.endsWith("角")) result += "整"; // 無分時

        return result;
    }

    // 測試
    public static void main(String[] args) {
        RMBConverter c = new RMBConverter();
        System.out.println(c.convert(2001004.10));   // 貳佰萬零壹仟零肆元壹角
        System.out.println(c.convert(2000000.10));   // 貳佰萬元壹角
        System.out.println(c.convert(0));            // 零元整
        System.out.println(c.convert(1121000010000000L)); // 壹仟壹佰貳拾壹兆... (超出長度演示)
        System.out.println(c.convert(-123.45));      // 負壹佰貳拾叁元肆角伍分
    }
}

關鍵測試用例與預期輸出

輸入輸出驗證點
2001004.10貳佰萬零壹仟零肆元壹角萬位零、仟位零、小數角
2000000.10貳佰萬元壹角連續零壓縮、萬位單位保留
0零元整零值特判
-123.45負壹佰貳拾叁元肆角伍分負數處理
1000.00壹仟元整無小數補「整」
0.01壹分純小數、無整數部分

避坑指南

  • 浮點數精度:用 BigDecimal 替代 double 做金額運算,避免 0.1+0.2=0.30000000000000004 問題。
  • Math.round 四捨五入:0.005 會變 0.01,符合財務習慣;若需截斷請用 BigDecimal.setScale(2, RoundingMode.DOWN)。
  • 超長數值:UNIT_INT 陣列長度決定最大支持到「兆」級,實際需求可動態生成單位陣列。
  • 線程安全:工具類無狀態,可做 static 單例或無狀態服務注入。

人民幣大寫轉換看似字符串拼接,實則蘊含嚴格的財務規範。掌握「逆序遍歷 + 零值壓縮正則 + 單位修正」三板斧,即可應對各種邊界場景。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved