using System.Runtime.CompilerServices; using YLErp.Commons; namespace System { /// /// 数字帮助类 /// public static class NumberHelper { /// /// 非四舍五入情况下截取最大小数位数字 /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static double Truncate(double value, int minDecimals, int maxDecimals, bool percent) { var decimals = maxDecimals > minDecimals ? maxDecimals : minDecimals; if (percent) { decimals += 2; } if (decimals > 0) { var pow = Math.Pow(10, decimals); return Math.Truncate(value * pow) / pow; } else { return Math.Truncate(value); } } public static decimal Truncate(decimal value, int minDecimals, int maxDecimals, bool percent) { var decimals = maxDecimals > minDecimals ? maxDecimals : minDecimals; if (percent) { decimals += 2; } if (decimals > 0) { var pow = Math.Pow(10, decimals); var dePow = Convert.ToDecimal(pow); return Math.Truncate(value * dePow) / dePow; } else { return Math.Truncate(value); } } /// /// 获取数字格式化字符串 /// /// 最小小数位 /// 最大小数位 /// 是否百分比格式 /// 是否千分位分组 [MethodImpl(MethodImplOptions.AggressiveInlining)] public static string GetFormat(int minDecimals, int maxDecimals, bool percent, bool grouping) { var sb = StringBuilderPool.Acquire(); sb.Append(grouping ? "#,##0" : "0"); if (minDecimals > 0) { sb.Append('.').Append('0', minDecimals); if (maxDecimals > minDecimals) { sb.Append('#', maxDecimals - minDecimals); } } else if (maxDecimals > 0) { sb.Append('.').Append('#', maxDecimals); } if (percent) { sb.Append('%'); } return sb.Release(); } /// /// 转换为中文数字 /// /// 数字 /// 金钱样式 public static string ConvertToChinese(double number, bool moneyStyle) { return moneyStyle ? ChineseNumberConvert.MoneyCn(number) : ChineseNumberConvert.NumberCn(number); } /// /// 转换为人民币大写 /// public static string CmycurD(double num) { return ChineseNumberConvert.CmycurD(num); } /// /// 小写转大写数字(整数) /// public static string CurrToChnInt(int n) { return ChineseNumberConvert.CurrToChnInt(n); } /// /// 正常化double值(NAN或无限大数字转换为0) /// public static double Normalize(this double value) { return double.IsNaN(value) || double.IsInfinity(value) ? 0 : value; } /// /// 正常化double值(NAN或无限大数字转换为0) /// public static double Normalize(this double? value) { return !value.HasValue || double.IsNaN(value.Value) || double.IsInfinity(value.Value) ? 0 : value.Value; } /// /// 检查double值是否为(NAN或无限大数字) /// /// /// public static bool IsNormalize(this double value) { return !(double.IsNaN(value) || double.IsInfinity(value)); } /// /// 检查double值是否为(NULL NAN或无限大数字) /// /// /// public static bool IsNormalize(this double? value) { return value.HasValue && value.Value.IsNormalize(); } /// /// 浮点数格式化 /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static string Format(double? d, string fmt) { return d.HasValue ? d.Value.ToString(fmt) : ""; } /// /// 字符串转换为doulbe数字 /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static double ToDouble(string str, double defaultValue = 0) { return double.TryParse(str, out var val) ? val : defaultValue; } /// /// decimal?转换为doulbe数字 /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static double ToDouble(this decimal? d, double defaultValue = 0) { return d.HasValue ? Convert.ToDouble(d) : defaultValue; } /// /// double转换为decimal(未处理double参数是否超出了decimal.MaxValue|MinValue的范围) /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static decimal ToDecimal(this double d, decimal defaultValue = 0) { return double.IsNaN(d) || double.IsInfinity(d) ? defaultValue : new decimal(d); } /// /// 尝试解析百分比数字(根据传入的字符层末尾是否为%判断) /// public static bool TryParse(string str, out double dvalue, out bool isPercent) { dvalue = 0; isPercent = false; if (string.IsNullOrWhiteSpace(str)) { return false; } isPercent = str.EndsWith("%"); if (isPercent) { str = str.TrimEnd('%'); } if (double.TryParse(str, out dvalue)) { if (isPercent) { dvalue /= 100; } return true; } return false; } /// /// doulbe取绝对值() /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static double Abs(double value) { return double.IsNaN(value) || double.IsInfinity(value) ? 0 : Math.Abs(value); } /// /// 中文数字转换类 /// static class ChineseNumberConvert { const string cPointCn = "点十百千万十百千亿十百千"; const string cNumberCn = "零一二三四五六七八九"; public static string NumberCn(string number) { var S = number.ToString(); if (S == "0") { return "" + cPointCn[0]; } if (!S.Contains(".")) { S += "."; } var P = S.IndexOf("."); var Result = ""; for (var i = 0; i < S.Length; i++) { if (P == i) { Result = Result.Replace("零十零", "零"); Result = Result.Replace("零百零", "零"); Result = Result.Replace("零千零", "零"); Result = Result.Replace("零十", "零"); Result = Result.Replace("零百", "零"); Result = Result.Replace("零千", "零"); Result = Result.Replace("零万", "万"); Result = Result.Replace("零亿", "亿"); Result = Result.Replace("亿万", "亿"); Result = Result.Replace("零点", "点"); } else { try { if (P > i) { Result += "" + cNumberCn[S[i] - '0'] + cPointCn[P - i - 1]; } else { Result += "" + cNumberCn[S[i] - '0']; } } catch { return ""; } } } if (Result.Substring(Result.Length - 1, 1) == "" + cPointCn[0]) { Result = Result.Remove(Result.Length - 1); // 一点-> 一 } if (Result[0] == cPointCn[0]) { Result = cNumberCn[0] + Result; // 点三-> 零点三 } if ((Result.Length > 1) && (Result[1] == cPointCn[1]) && (Result[0] == cNumberCn[1])) { Result = Result.Remove(0, 1); // 一十三-> 十三 } return Result; } public static string NumberCn(double number) { return NumberCn(number.ToString()); } /// /// 2021年7月20日微调 /// /// /// public static string MoneyCn(double number) { if (number == 0) { return "零"; } /* * 修改原因是因为142,547.580 使用Math.Truncate(number * 100)后 * 变为142,547.570 */ var Result = NumberCn(Math.Truncate(number * 100 + 1e-6) / 100); Result = Result.Replace("一", "壹"); Result = Result.Replace("二", "贰"); Result = Result.Replace("三", "叁"); Result = Result.Replace("四", "肆"); Result = Result.Replace("五", "伍"); Result = Result.Replace("六", "陆"); Result = Result.Replace("七", "柒"); Result = Result.Replace("八", "捌"); Result = Result.Replace("九", "玖"); Result = Result.Replace("九", "玖"); Result = Result.Replace("十", "拾"); Result = Result.Replace("百", "佰"); Result = Result.Replace("千", "仟"); if (Result.Contains("点")) { var P = Result.IndexOf("点"); if (Result.Length >= P + 3) { Result = Result.Insert(P + 3, "分"); } Result = Result.Insert(P + 2, "角"); Result = Result.Replace("点", "圆"); Result = Result.Replace("角分", "角"); Result = Result.Replace("零分", ""); Result = Result.Replace("零角", ""); Result = Result.Replace("分角", ""); if (Result.Substring(0, 2) == "零圆") { Result = Result.Replace("零圆", ""); } } else { Result += "圆整"; } Result = "人民币" + Result; return Result; } /// /// 转换为人民币大写 /// public static string CmycurD(double num) { var str1 = "零壹贰叁肆伍陆柒捌玖"; //0-9所对应的汉字 var str2 = "万仟佰拾亿仟佰拾万仟佰拾元角分"; //数字位所对应的汉字 var str3 = ""; //从原num值中取出的值 var str4 = ""; //数字的字符串形式 var str5 = ""; //人民币大写金额形式 int i; //循环变量 int j; //num的值乘以100的字符串长度 var ch1 = ""; //数字的汉语读法 var ch2 = ""; //数字位的汉字读法 var nzero = 0; //用来计算连续的零值是几个 int temp; //从原num值中取出的值 num = double.Parse(num.ToString("0.##")); //将num取绝对值并四舍五入取2位小数 str4 = Math.Round(num * 100).ToString("F0"); //将num乘100并转换成字符串形式 j = str4.Length; //找出最高位 if (j > 15) { return "溢出"; } str2 = str2.Substring(15 - j); //取出对应位数的str2的值。如:200.55,j为5所以str2=佰拾元角分 //循环取出每一位需要转换的值 for (i = 0; i < j; i++) { str3 = str4.Substring(i, 1); //取出需转换的某一位的值 temp = Convert.ToInt32(str3); //转换为数字 if (i != (j - 3) && i != (j - 7) && i != (j - 11) && i != (j - 15)) { //当所取位数不为元、万、亿、万亿上的数字时 if (str3 == "0") { ch1 = ""; ch2 = ""; nzero += 1; } else { if (str3 != "0" && nzero != 0) { ch1 = "零" + str1.Substring(temp * 1, 1); ch2 = str2.Substring(i, 1); nzero = 0; } else { ch1 = str1.Substring(temp * 1, 1); ch2 = str2.Substring(i, 1); nzero = 0; } } } else { //该位是万亿,亿,万,元位等关键位 if (str3 != "0" && nzero != 0) { ch1 = "零" + str1.Substring(temp * 1, 1); ch2 = str2.Substring(i, 1); nzero = 0; } else { if (str3 != "0" && nzero == 0) { ch1 = str1.Substring(temp * 1, 1); ch2 = str2.Substring(i, 1); nzero = 0; } else { if (str3 == "0" && nzero >= 3) { ch1 = ""; ch2 = ""; nzero += 1; } else { //if (j > 11) //{ // ch1 = ""; // nzero += 1; //} //else //{ ch1 = ""; ch2 = str2.Substring(i, 1); nzero += 1; //} } } } } if (i == (j - 11) || i == (j - 3)) { //如果该位是亿位或元位,则必须写上 ch2 = str2.Substring(i, 1); } str5 = str5 + ch1 + ch2; if (i == j - 1 && str3 == "0") { //最后一位(分)为0时,加上“整” str5 += '整'; } } if (num == 0) { str5 = "零元整"; } return str5; } /// /// 小写转大写数字(整数) /// 这个从otcformathelper迁移过来,最好也调用NumberCn /// public static string CurrToChnInt(int n) { string[] c_Num1 = { "零", "一", "二", "三", "四", "五", "六", "七", "八", "九" }; string[] c_fh = { "", "十", "百", "千", "万" }; string s = n.ToString(); string ss = ""; int j = s.Length - 1; for (int i = 0; i <= j; i++) { int num = Convert.ToInt32(s.Substring(i, 1)); if (j == i) { if (j == 0 || num != 0) { ss += c_Num1[num]; } } else { if (num == 1) { ss += c_fh[j - i]; } else { ss += c_Num1[num] + c_fh[j - i]; } } } return ss; } } } }