You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

189 lines
5.1 KiB

1 month ago
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<int> 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<int>();
}
var list = new List<int>(range);
for (int i = 0; i < range; i++)
{
list.Add(min + i);
}
var rand = new Random();
var ret = new List<int>(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;
}
}
}