NumberFormater.cs 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Globalization;
  4. using System.Linq;
  5. using System.Text.RegularExpressions;
  6. namespace Masuit.Tools.Strings
  7. {
  8. /// <summary>
  9. /// 数制格式化器
  10. /// </summary>
  11. public class NumberFormater
  12. {
  13. /// <summary>
  14. /// 数制表示字符集
  15. /// </summary>
  16. private string Characters { get; set; }
  17. /// <summary>
  18. /// 进制长度
  19. /// </summary>
  20. public int Length => Characters?.Length ?? 0;
  21. /// <summary>
  22. /// 数制格式化器
  23. /// </summary>
  24. public NumberFormater()
  25. {
  26. Characters = "0123456789";
  27. }
  28. /// <summary>
  29. /// 数制格式化器
  30. /// </summary>
  31. /// <param name="characters">进制转换</param>
  32. public NumberFormater(string characters)
  33. {
  34. Characters = characters;
  35. }
  36. /// <summary>
  37. /// 数制格式化器
  38. /// </summary>
  39. /// <param name="bin">进制</param>
  40. public NumberFormater(int bin)
  41. {
  42. if (bin < 2)
  43. {
  44. bin = 2;
  45. }
  46. if (bin > 62)
  47. {
  48. throw new ArgumentException("进制最大支持62进制");
  49. }
  50. Characters = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ".Substring(0, bin);
  51. }
  52. /// <summary>
  53. /// 数字转换为指定的进制形式字符串
  54. /// </summary>
  55. /// <param name="number"></param>
  56. /// <returns></returns>
  57. public string ToString(long number)
  58. {
  59. List<string> result = new List<string>();
  60. long t = number;
  61. while (t > 0)
  62. {
  63. var mod = t % Length;
  64. t = Math.Abs(t / Length);
  65. var character = Characters[Convert.ToInt32(mod)].ToString();
  66. result.Insert(0, character);
  67. }
  68. return string.Join("", result.ToArray());
  69. }
  70. /// <summary>
  71. /// 指定字符串转换为指定进制的数字形式
  72. /// </summary>
  73. /// <param name="str"></param>
  74. /// <returns></returns>
  75. public long FromString(string str)
  76. {
  77. int j = 0;
  78. return new string(str.ToCharArray().Reverse().ToArray()).Where(ch => Characters.Contains(ch)).Sum(ch => Characters.IndexOf(ch) * (long)Math.Pow(Length, j++));
  79. }
  80. /// <summary>Returns a string that represents the current object.</summary>
  81. /// <returns>A string that represents the current object.</returns>
  82. public override string ToString()
  83. {
  84. return Length + "模式";
  85. }
  86. // 转换数字
  87. private static char ToNum(char x)
  88. {
  89. string strChnNames = "零一二三四五六七八九";
  90. string strNumNames = "0123456789";
  91. return strChnNames[strNumNames.IndexOf(x)];
  92. }
  93. // 转换万以下整数
  94. private static string ChangeInt(string x)
  95. {
  96. string[] strArrayLevelNames = { "", "十", "百", "千" };
  97. string ret = "";
  98. int i;
  99. for (i = x.Length - 1; i >= 0; i--)
  100. {
  101. if (x[i] == '0')
  102. {
  103. ret = ToNum(x[i]) + ret;
  104. }
  105. else
  106. {
  107. ret = ToNum(x[i]) + strArrayLevelNames[x.Length - 1 - i] + ret;
  108. }
  109. }
  110. while ((i = ret.IndexOf("零零", StringComparison.Ordinal)) != -1)
  111. {
  112. ret = ret.Remove(i, 1);
  113. }
  114. if (ret[^1] == '零' && ret.Length > 1)
  115. {
  116. ret = ret.Remove(ret.Length - 1, 1);
  117. }
  118. if (ret.Length >= 2 && ret.Substring(0, 2) == "一十")
  119. {
  120. ret = ret.Remove(0, 1);
  121. }
  122. return ret;
  123. }
  124. // 转换整数
  125. private static string ToInt(string x)
  126. {
  127. int len = x.Length;
  128. string result;
  129. string temp;
  130. if (len <= 4)
  131. {
  132. result = ChangeInt(x);
  133. }
  134. else if (len <= 8)
  135. {
  136. result = ChangeInt(x.Substring(0, len - 4)) + "万";
  137. temp = ChangeInt(x.Substring(len - 4, 4));
  138. if (temp.IndexOf("千", StringComparison.Ordinal) == -1 && !string.IsNullOrEmpty(temp))
  139. {
  140. result += "零" + temp;
  141. }
  142. else
  143. {
  144. result += temp;
  145. }
  146. }
  147. else
  148. {
  149. result = ChangeInt(x.Substring(0, len - 8)) + "亿";
  150. temp = ChangeInt(x.Substring(len - 8, 4));
  151. if (temp.IndexOf("千", StringComparison.Ordinal) == -1 && !string.IsNullOrEmpty(temp))
  152. {
  153. result += "零" + temp;
  154. }
  155. else
  156. {
  157. result += temp;
  158. }
  159. result += "万";
  160. temp = ChangeInt(x.Substring(len - 4, 4));
  161. if (temp.IndexOf("千", StringComparison.Ordinal) == -1 && !string.IsNullOrEmpty(temp))
  162. {
  163. result += "零" + temp;
  164. }
  165. else
  166. {
  167. result += temp;
  168. }
  169. }
  170. int i;
  171. if ((i = result.IndexOf("零万", StringComparison.Ordinal)) != -1)
  172. {
  173. result = result.Remove(i + 1, 1);
  174. }
  175. while ((i = result.IndexOf("零零", StringComparison.Ordinal)) != -1)
  176. {
  177. result = result.Remove(i, 1);
  178. }
  179. if (result[^1] == '零' && result.Length > 1)
  180. {
  181. result = result.Remove(result.Length - 1, 1);
  182. }
  183. return result;
  184. }
  185. /// <summary>
  186. /// 转换为中文数字格式
  187. /// </summary>
  188. /// <param name="num">123.45</param>
  189. /// <returns></returns>
  190. public static string ToChineseNumber(double num)
  191. {
  192. var x = num.ToString(CultureInfo.CurrentCulture);
  193. if (x.Length == 0)
  194. {
  195. return "";
  196. }
  197. string result = "";
  198. if (x[0] == '-')
  199. {
  200. result = "负";
  201. x = x.Remove(0, 1);
  202. }
  203. if (x[0].ToString() == ".")
  204. {
  205. x = "0" + x;
  206. }
  207. if (x[^1].ToString() == ".")
  208. {
  209. x = x.Remove(x.Length - 1, 1);
  210. }
  211. if (x.IndexOf(".") > -1)
  212. {
  213. result += ToInt(x.Substring(0, x.IndexOf("."))) + "点" + x.Substring(x.IndexOf(".") + 1).Aggregate("", (current, t) => current + ToNum(t));
  214. }
  215. else
  216. {
  217. result += ToInt(x);
  218. }
  219. return result;
  220. }
  221. /// <summary>
  222. /// 数字转中文金额大写
  223. /// </summary>
  224. /// <param name="number">22.22</param>
  225. /// <returns></returns>
  226. public static string ToChineseMoney(double number)
  227. {
  228. string s = number.ToString("#L#E#D#C#K#E#D#C#J#E#D#C#I#E#D#C#H#E#D#C#G#E#D#C#F#E#D#C#.0B0A");
  229. string d = Regex.Replace(s, @"((?<=-|^)[^1-9]*)|((?'z'0)[0A-E]*((?=[1-9])|(?'-z'(?=[F-L\.]|$))))|((?'b'[F-L])(?'z'0)[0A-L]*((?=[1-9])|(?'-z'(?=[\  .]|$))))", "${b}${z}");
  230. return Regex.Replace(d, ".", m => "负元空零壹贰叁肆伍陆柒捌玖空空空空空空空分角拾佰仟萬億兆京垓秭穰"[m.Value[0] - '-'].ToString());
  231. }
  232. }
  233. }