您的位置:首页 > 其它

金额小写转中文大写

2014-02-06 17:41 330 查看
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;

    }

}

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  money