[英]What is the fastest way to discretize double in C#?
我有一個介於 -1 和 1 之間的雙精度值。
我需要將它離散化 N 步,它非常非常快。 如果 N 為 5,我的最終值將是以下之一:
-1,-0.8,-0.6,-0.4,-0.2,0,0.2,0.4,0.6,0.8,1
我需要一個 function:
double discretize(double value)
例如:
discretize(0.091231) = 0
discretize(0.192312) = 0.2
我想知道尾數/指數是否有任何技巧,通過位移等使其離散......而不進行任何浮點運算。
聽起來像一個舍入操作。
static class Program
{
static readonly Random rng = new Random();
static void Main(string[] args)
{
for (int i = 0; i < 15; i++)
{
var x = rng.NextDouble();
Debug.WriteLine($"{x,-15} = {x.Quantize(5)}");
}
}
public static double Quantize(this double x, int steps)
{
return Math.Round(x*steps)/steps;
}
}
使用程序 output
0.45652442819277 = 0.4
0.649511796259094 = 0.6
0.605691870490877 = 0.6
0.685007393679119 = 0.6
0.489223629929695 = 0.4
0.496371834304357 = 0.4
0.153276258685289 = 0.2
0.212714763457288 = 0.2
0.0338650732458872 = 0
0.0612733452866195 = 0
0.258718123314305 = 0.2
0.906546349593693 = 1
0.39698489727312 = 0.4
0.728462797928817 = 0.8
0.140497107589849 = 0.2
PS。 由於您在回合后進行除法,因此最好使用ToEven
選項
Math.Round(x*steps, MidpointRounding.ToEven)/steps
如果您想要更快的速度,請從double
切換到float
,並使用System.Numerics
中的函數在向量中加載多個值。
還使用積極的內聯來裝飾函數,這反過來有更好的機會通過 JIT 生成矢量化代碼。
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static double Quantize(this double x, int steps)
{
return Math.Round(x*steps)/steps;
}
最后,考慮使用庫使用 C++ 甚至更好的 Fortran(甚至可能是 Julia)進行此數學處理。
迄今為止最快的方法:
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static double Quantize(this double x, int steps)
{
return ((double)((int)(x*steps+0.5)))/steps;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.