精度的处理

using System;
  2using System.Collections.Generic;
  3using System.Text;
  4
  5namespace CSharp大写金额
  6{
  7    /** <summary>
  8    /// 将实数转化为中文大写金额
  9    /// 作者:左轮
 10    /// 时间:2007-11-4
 11    /// </summary>
 12    public static class ConvertDoubleToChineseMoney
 13    {
 14        /** <summary>
 15        /// 数字和中文大写字符对应关系
 16        /// </summary>
 17        private static Dictionary<int, string> _numberChinese;
 18        /** <summary>
 19        /// 位数和位名(如个、拾、百等)对应关系
 20        /// </summary>
 21        private static Dictionary<int, string> _pointChineseNames;
 22        /** <summary>
 23        /// 最大位名对应的位数
 24        /// </summary>
 25        private const int _maxPointNameIndex = 8;
 26
 27        static ConvertDoubleToChineseMoney()
 28        {
 29            _numberChinese = new Dictionary<int, string>(10);
 30            _numberChinese.Add(0, "零");
 31            _numberChinese.Add(1, "壹");
 32            _numberChinese.Add(2, "贰");
 33            _numberChinese.Add(3, "叁");
 34            _numberChinese.Add(4, "肆");
 35            _numberChinese.Add(5, "伍");
 36            _numberChinese.Add(6, "陆");
 37            _numberChinese.Add(7, "柒");
 38            _numberChinese.Add(8, "扒");
 39            _numberChinese.Add(9, "玖");
 40
 41            _pointChineseNames = new Dictionary<int, string>(8);
 42            _pointChineseNames.Add(_maxPointNameIndex, "亿");
 43            _pointChineseNames.Add(4, "万");
 44            _pointChineseNames.Add(3, "仟");
 45            _pointChineseNames.Add(2, "佰");
 46            _pointChineseNames.Add(1, "拾");
 47            _pointChineseNames.Add(0, string.Empty);
 48            _pointChineseNames.Add(-1, "角");
 49            _pointChineseNames.Add(-2, "分");
 50        }
 51
 52        /** <summary>
 53        /// 将实数转化为中文大写金额
 54        /// </summary>
 55        /// <param name="money">用双精度浮点数表示的金额,不能大于9.0e+15,否则抛出ArgumentException异常</param>
 56        /// <returns>中文大写金额字符串</returns>
 57        public static string Convert(double money)
 58        {
 59            if (money > 9.0e+15)
 60                throw new ArgumentException("不能转换大于9.0e+15的数");
 61
 62            if (money < 0.01)
 63                return "零元";
 64
 65            //分开小数点左边和右边两部分分别转换,然后再合并
 66            double rightPart = money % 1D;
 67            double leftPart = money - rightPart;
 68
 69            string strLeftPart = ConvertLeftPart(leftPart);
 70            string strRightPart = ConvertRightPart(rightPart);
 71
 72            StringBuilder sbChineseMoney = new StringBuilder(strLeftPart.Length + strRightPart.Length + 2);
 73            if (string.IsNullOrEmpty(strLeftPart))
 74            {
 75                strRightPart = strRightPart.TrimStart('零');
 76            }
 77            else
 78            {
 79                sbChineseMoney.Append(strLeftPart);
 80                sbChineseMoney.Append('元');
 81            }
 82            sbChineseMoney.Append(strRightPart);
 83
 84            return sbChineseMoney.ToString();
 85        }
 86
 87        /** <summary>
 88        /// 转换小数点左边部分
 89        /// </summary>
 90        /// <param name="money"></param>
 91        /// <returns></returns>
 92        private static string ConvertLeftPart(double money)
 93        {
 94            //中文大写金额,结果字符串
 95            StringBuilder sbChineseMoney = new StringBuilder(_maxPointNameIndex * 2);
 96            bool isBegin = false;
 97            //从左到右逐个将字翻译成中文大写金额
 98            for (int numberIndex = _maxPointNameIndex * 2 - 1; numberIndex >= 0; numberIndex--)
 99            {
100                //获取一位上的数字
101                double number = GetNumbers(money, numberIndex, numberIndex);
102
103                if (number > 0)
104                    isBegin = true;
105
106                if (number == 0 && !isBegin)
107                    continue;
108                //获取位名的key
109                int pointNameIndex = GetLeftPartPointNameIndex(numberIndex);
110                //将当前数字的中文字符和位名插入结果字符串
111                if (number != 0)
112                {
113                    //当前数字不为零,将数字和位名直接加入结果字符串尾部
114                    sbChineseMoney.Append(_numberChinese[(int)number]);
115                    sbChineseMoney.Append(_pointChineseNames[pointNameIndex]);
116                }
117                else
118                {
119                    //当前数字为零
120                    //如果结果字符串最后一个字符不是零,才将零加入结果字符串,避免多个相邻的零出现在结果字符串
121                    if (sbChineseMoney[sbChineseMoney.Length - 1] != '零')
122                        sbChineseMoney.Append('零');
123                    //如果位名是个、拾、百、千,不出现在零后面
124                    //处理位名是万、亿的情况
125                    if (pointNameIndex >= 4 && GetNumbers(money, numberIndex + pointNameIndex - 1, numberIndex) > 0D)
126                        sbChineseMoney = sbChineseMoney.Insert(sbChineseMoney.Length - 1, _pointChineseNames[pointNameIndex]);
127                }
128
129            }
130            string strChineseMoney = sbChineseMoney.ToString();
131            strChineseMoney = strChineseMoney.TrimEnd('零');
132            return strChineseMoney;
133        }
134
135        /** <summary>
136        /// 处理小数点右边部分
137        /// </summary>
138        /// <param name="money"></param>
139        /// <returns></returns>
140        private static string ConvertRightPart(double money)
141        {
142            if( money < 0.01 )
143                return string.Empty;
144
145            money *= 100;
146
147            StringBuilder sbChineseMoney = new StringBuilder(4);
148
149            int number = (int)GetNumbers(money, 1, 1);
150            sbChineseMoney.Append(_numberChinese[number]);
151            if (number != 0)
152                sbChineseMoney.Append(_pointChineseNames[-1]);
153
154            number = (int)GetNumbers(money, 0, 0);
155            if (number != 0)
156            {
157                sbChineseMoney.Append(_numberChinese[number]);
158                sbChineseMoney.Append(_pointChineseNames[-2]);
159            }
160
161            return sbChineseMoney.ToString();
162        }
163        /** <summary>
164        /// 获取指定位数范围的数字
165        /// </summary>
166        /// <param name="money"></param>
167        /// <param name="leftIndex"></param>
168        /// <param name="rightIndex"></param>
169        /// <returns></returns>
170        private static double GetNumbers(double money, int leftIndex, int rightIndex)
171        {
172            double pow1 = Math.Pow(10D, (double)(leftIndex + 1));
173            double pow2 =  Math.Pow(10D, (double)rightIndex);
174            return (money % pow1 - money % pow2) / pow2;
175        }
176
177        /** <summary>
178        /// 获取指定数字索引的位名在_pointChineseNames上的key
179        /// </summary>
180        /// <param name="numberIndex"></param>
181        /// <param name="name"></param>
182        /// <returns>位名在_pointChineseNames上的key</returns>
183        private static int GetLeftPartPointNameIndex(int numberIndex)
184        {
185            int pointNameIndex = 0;
186            int remainder = numberIndex % 4;
187            if (remainder == 0)
188            {
189                if (numberIndex == 0)
190                {
191                    pointNameIndex = 0;
192                }
193                else
194                {
195                    for (int cast = _maxPointNameIndex; cast >= 4; cast /= 2)
196                    {
197                        if (numberIndex % cast == 0)
198                        {
199                            pointNameIndex = cast;
200                            break;
201                        }
202                    }
203                }
204            }
205            else
206            {
207                pointNameIndex = remainder;
208            }
209
210            return pointNameIndex;
211        }
212    }
213}

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/wuyq11/archive/2007/11/04/1865699.aspx

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值