精度的处理

using System;
2 using System.Collections.Generic;
3 using System.Text;
4
5 namespace CSharp大写金额
6 {
7 ///
8 /// 将实数转化为中文大写金额
9 /// 作者:左轮
10 /// 时间:2007-11-4
11 ///
12 public static class ConvertDoubleToChineseMoney
13 {
14 ///
15 /// 数字和中文大写字符对应关系
16 ///
17 private static Dictionary<int, string> _numberChinese;
18 ///
19 /// 位数和位名(如个、拾、百等)对应关系
20 ///
21 private static Dictionary<int, string> _pointChineseNames;
22 ///
23 /// 最大位名对应的位数
24 ///
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 ///
53 /// 将实数转化为中文大写金额
54 ///
55 /// 用双精度浮点数表示的金额,不能大于9.0e+15,否则抛出ArgumentException异常
56 /// 中文大写金额字符串
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 ///
88 /// 转换小数点左边部分
89 ///
90 ///
91 ///
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 ///
136 /// 处理小数点右边部分
137 ///
138 ///
139 ///
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 ///
164 /// 获取指定位数范围的数字
165 ///
166 ///
167 ///
168 ///
169 ///
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 ///
178 /// 获取指定数字索引的位名在_pointChineseNames上的key
179 ///
180 ///
181 ///
182 /// 位名在_pointChineseNames上的key
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}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值