using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace Sog { public static class MathUtils { public static int MAX_RAND_RANGE = 10000; private static long CHIP_LEVEL_1 = 1000000; // 从[min, max]中随机取need个整数,need大于区间长度时,返回数中出现重复数字 public static List GetRandomList(int min, int max, int need) { int range = max - min + 1; if (range <= 0 || range > MAX_RAND_RANGE) { TraceLog.Error("MathUtils.GetRandomList range {0} is great than max {1}", range, MAX_RAND_RANGE); return new List(); } var list = new List(range); for (int i = 0; i < range; i++) { list.Add(min + i); } var rand = new Random(); var ret = new List(need); int size = range; for (int i = 0; i < need; i++) { if (size == 0) { size = range; } int idx = rand.Next(size); ret.Add(list[idx]); int tmp = list[idx]; list[idx] = list[size - 1]; list[size - 1] = tmp; size--; } return ret; } public static string NumberToStringTK(long num) { bool negative = false; if (num < 0) { negative = true; num = -num; } string output = ""; long integerPart = num; // 超过1000000的以M为单位显示,小数点后最多显示2位,如1.68M if (num >= CHIP_LEVEL_1) { integerPart = num / CHIP_LEVEL_1; long fractionalPart = num % CHIP_LEVEL_1; fractionalPart = fractionalPart / 10000; if (fractionalPart > 0) { output = string.Format(",{0:D2}M", fractionalPart); } else { output = "M"; } } // 剩余整数部分每3位以"."分格,如123456789012345 = 123.456.789,01M while (integerPart >= 1000) { long tmp = integerPart / 1000; long remain = integerPart % 1000; output = string.Format(".{0:D3}{1}", remain, output); integerPart = tmp; } output = string.Format("{0}{1}", integerPart, output); if (negative) { output = "-" + output; } return output; } public static double Erf(double x) { // constants double a1 = 0.254829592; double a2 = -0.284496736; double a3 = 1.421413741; double a4 = -1.453152027; double a5 = 1.061405429; double p = 0.3275911; // Save the sign of x int sign = 1; if (x < 0) sign = -1; x = Math.Abs(x); // A&S formula 7.1.26 double t = 1.0 / (1.0 + p * x); double y = 1.0 - (((((a5 * t + a4) * t) + a3) * t + a2) * t + a1) * t * Math.Exp(-x * x); return sign * y; } public static string FormatNumber(long num, int decimals = 2) { double exponent = 0; string formatNum; if (decimals > 0) { exponent = Math.Pow(10, decimals); } if (num > 999999999999) { var resullt = Math.Floor(num * 1.0 / 1000000000000 * exponent) / exponent; formatNum = resullt.ToString() + "T"; } else if (num > 999999999) { var resullt = Math.Floor(num * 1.0 / 1000000000 * exponent) / exponent; formatNum = resullt.ToString() + "B"; } else if (num > 999999) { var resullt = Math.Floor(num * 1.0 / 1000000 * exponent) / exponent; formatNum = resullt.ToString() + "M"; } else if (num > 9999) { var resullt = Math.Floor(num * 1.0 / 1000 * exponent) / exponent; formatNum = resullt.ToString() + "K"; } else { formatNum = num.ToString(); } return formatNum; } //快速平方根算法 unsafe public static double FastSqrtIEEE(double number) { long i; double x, y; const double threehalfs = 1.5f; y = number; x = number * 0.5f; i = *(long*)&y; i = 0x5fe6ec85e7de30daL - (i >> 1); y = *(double*)&i; y *= threehalfs - (x * y * y); y *= threehalfs - (x * y * y); return number * y; } } }