NumberFormater.cs 9.2 KB

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