using System;
2
using System.Collections.Generic;
3
using System.Text;
4
5
namespace 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
}
2

3

4

5

6



7


8

9

10

11

12

13



14


15

16

17

18


19

20

21

22


23

24

25

26

27

28



29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52


53

54

55

56

57

58



59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74



75

76

77

78



79

80

81

82

83

84

85

86

87


88

89

90

91

92

93



94

95

96

97

98

99



100

101

102

103

104

105

106

107

108

109

110

111

112



113

114

115

116

117

118



119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135


136

137

138

139

140

141



142

143

144

145

146

147

148

149

150

151

152

153

154

155

156



157

158

159

160

161

162

163


164

165

166

167

168

169

170

171



172

173

174

175

176

177


178

179

180

181

182

183

184



185

186

187

188



189

190



191

192

193

194



195

196



197

198



199

200

201

202

203

204

205

206



207

208

209

210

211

212

213
