c# - 在 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
我需要一个函数:
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;
}
}
与程序输出
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
to切换float
并使用 in 函数System.Numerics
在向量中加载多个值。
还使用积极的内联来装饰函数,这反过来有更好的机会通过 JIT 生成矢量化代码。
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static double Quantize(this double x, int steps)
{
return Math.Round(x*steps)/steps;
}
最后,考虑使用 C++ 甚至更好的 Fortran(甚至可能是 Julia)使用库来进行这种数学处理。
推荐阅读
- flutter - 我可以让 ListView 中的项目超出容器限制吗?
- python - 一个奇怪的泡菜故障
- firebase - 什么时候一起使用 Firebase 实时数据库和 Firestore 才有意义?
- cocoa - Cocoapod:警告:URI.escape 已过时
- node.js - Nodejs 重复拒绝(未处理的一个并在 try/catch 块中)
- vb.net - Visual Basic 中的 2D 碰撞检测
- javascript - Mongoose:E11000 重复键改变返回消息的类型以防出错
- r - 二元逻辑回归输出
- javascript - 如何为此对象编写打字稿声明文件?
- python-3.x - 为什么读取上传文件和读取本地文件会产生不同的结果?