金额小写转中文大写

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Text;

/// <summary>
/// ConvertDoubleToChineseMoney 的摘要描述
/// </summary>
public class ConvertDoubleToChineseMoney
{
    /// <summary>
    /// 數位和中文大寫字元對應關係
    /// </summary>
    private static Dictionary<int, string> _numberChinese;
    /// <summary>
    /// 位數和位名(如個、拾、百等)對應關係
    /// </summary>
    private static Dictionary<int, string> _pointChineseNames;
    /// <summary>
    /// 最大位名對應的位數
    /// </summary>
    private const int _maxPointNameIndex = 8;

    static ConvertDoubleToChineseMoney()
    {
        _numberChinese = new Dictionary<int, string>(10);
        _numberChinese.Add(0, "零");
        _numberChinese.Add(1, "壹");
        _numberChinese.Add(2, "貳");
        _numberChinese.Add(3, "叁");
        _numberChinese.Add(4, "肆");
        _numberChinese.Add(5, "伍");
        _numberChinese.Add(6, "陸");
        _numberChinese.Add(7, "柒");
        _numberChinese.Add(8, "捌");
        _numberChinese.Add(9, "玖");
        _pointChineseNames = new Dictionary<int, string>(8);
        _pointChineseNames.Add(_maxPointNameIndex, "億");
        _pointChineseNames.Add(4, "萬");
        _pointChineseNames.Add(3, "仟");
        _pointChineseNames.Add(2, "佰");
        _pointChineseNames.Add(1, "拾");
        _pointChineseNames.Add(0, string.Empty);
        _pointChineseNames.Add(-1, "角");
        _pointChineseNames.Add(-2, "分");
    }
    /// <summary>
    /// 將實數轉化為中文大寫金額
    /// </summary>
    /// <param name="money">用雙精度浮點數表示的金額,不能大於9.0e+15,否則拋出ArgumentException異常</param>
    /// <returns>中文大寫金額字串</returns>
    public static string ConvertMoney(double money)
    {
        if (money > 9.0e+15)
        {
            throw new ArgumentException("不能轉換大於9.0e+15的數");
        }
        if (money < 0.01)
        {
            return "零元";
        }
        //分開小數點左邊和右邊兩部分分別轉換,然後再合併
        string strMoney = money.ToString();
        double rightPart = 0;
        if (strMoney.Contains("."))
        {
            rightPart = Convert.ToDouble("0."+strMoney.Split('.')[1]);
        }

        //double rightPart = money % 1D;
        double leftPart = money - rightPart;

        string strLeftPart = ConvertLeftPart(leftPart);
        string strRightPart = ConvertRightPart(rightPart);

        StringBuilder sbChineseMoney = new StringBuilder(strLeftPart.Length + strRightPart.Length + 2);
        if (string.IsNullOrEmpty(strLeftPart))
        {
            strRightPart = strRightPart.TrimStart('零');
        }
        else
        {
            sbChineseMoney.Append(strLeftPart);
            sbChineseMoney.Append('元');
        }
        sbChineseMoney.Append(strRightPart);

        return sbChineseMoney.ToString();
    }

    /// <summary>
    /// 轉換小數點左邊部分
    /// </summary>
    /// <param name="money"></param>
    /// <returns></returns>
    private static string ConvertLeftPart(double money)
    {
        //中文大寫金額,結果字串
        StringBuilder sbChineseMoney = new StringBuilder(_maxPointNameIndex * 2);
        bool isBegin = false;
        //從左到右逐個將字翻譯成中文大寫金額
        for (int numberIndex = _maxPointNameIndex * 2 - 1; numberIndex >= 0; numberIndex--)
        {
            //獲取一位元上的數字
            double number = GetNumbers(money, numberIndex, numberIndex);
            if (number > 0)
            {
                isBegin = true;
            }
            if (number == 0 && !isBegin)
            {
                continue;
            }
            //獲取位名的key
            int pointNameIndex = GetLeftPartPointNameIndex(numberIndex);
            //將當前數位元的中文字元和位元元名插入結果字串
            if (number != 0)
            {
                //當前數位不為零,將數字和位元名直接加入結果字串尾部
                sbChineseMoney.Append(_numberChinese[(int)number]);
                sbChineseMoney.Append(_pointChineseNames[pointNameIndex]);
            }
            else
            {
                //當前數字為零
                //如果結果字串最後一個字元不是零,才將零加入結果字串,避免多個相鄰的零出現在結果字串
                if (sbChineseMoney[sbChineseMoney.Length - 1] != '零')
                    sbChineseMoney.Append('零');
                //如果位名是個、拾、百、千,不出現在零後面
                //處理位元名是萬、億的情況
                if (pointNameIndex >= 4 && GetNumbers(money, numberIndex + pointNameIndex - 1, numberIndex) > 0D)
                    sbChineseMoney = sbChineseMoney.Insert(sbChineseMoney.Length - 1, _pointChineseNames[pointNameIndex]);
            }
        }
        string strChineseMoney = sbChineseMoney.ToString();
        strChineseMoney = strChineseMoney.TrimEnd('零');
        return strChineseMoney;
    }
    /// <summary>
    /// 處理小數點右邊部分
    /// </summary>
    /// <param name="money"></param>
    /// <returns></returns>
    private static string ConvertRightPart(double money)
    {
        if (money < 0.01)
        {
            return string.Empty;
        }
        money *= 100;
        StringBuilder sbChineseMoney = new StringBuilder(4);
        int number = (int)GetNumbers(money, 1, 1);
        sbChineseMoney.Append(_numberChinese[number]);
        if (number != 0)
        {
            sbChineseMoney.Append(_pointChineseNames[-1]);
        }
        number = (int)GetNumbers(money, 0, 0);
        if (number != 0)
        {
            sbChineseMoney.Append(_numberChinese[number]);
            sbChineseMoney.Append(_pointChineseNames[-2]);
        }
        return sbChineseMoney.ToString();
    }
    /// <summary>
    /// 獲取指定位元數範圍的數字
    /// </summary>
    /// <param name="money"></param>
    /// <param name="leftIndex"></param>
    /// <param name="rightIndex"></param>
    /// <returns></returns>
    private static double GetNumbers(double money, int leftIndex, int rightIndex)
    {
        double pow1 = Math.Pow(10D, (double)(leftIndex + 1));
        double pow2 = Math.Pow(10D, (double)rightIndex);
        return (money % pow1 - money % pow2) / pow2;
    }
    /// <summary>
    /// 獲取指定數位元索引的位元元名在_pointChineseNames上的key
    /// </summary>
    /// <param name="numberIndex"></param>
    /// <param name="name"></param>
    /// <returns>位名在_pointChineseNames上的key</returns>
    private static int GetLeftPartPointNameIndex(int numberIndex)
    {
        int pointNameIndex = 0;
        int remainder = numberIndex % 4;
        if (remainder == 0)
        {
            if (numberIndex == 0)
            {
                pointNameIndex = 0;
            }
            else
            {
                for (int cast = _maxPointNameIndex; cast >= 4; cast /= 2)
                {
                    if (numberIndex % cast == 0)
                    {
                        pointNameIndex = cast;
                        break;
                    }
                }
            }
        }
        else
        {
            pointNameIndex = remainder;
        }
        return pointNameIndex;
    }

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值