首页 > 解决方案 > C# 随机浮点闭区间

问题描述

我很惊讶我在任何地方都找不到答案,所以也许我错过了一些东西。

类的NextDouble方法System.Random返回范围内的双精度数[0.0,1.0)。这是一个返回的半开区间0.0 <= x < 1.0

我需要一个封闭的区间[0.0,1.0],这样0.0 <= x <= 1.0。在 C++ 中,我可以使用std::nextafter,它返回大于传递参数的最小可表示浮点(例如std::nextafter(1.0, 2.0)将返回1.0000001192092895508)。我似乎在 C# 中找不到等价物。

我正在处理大量高精度数字(16 位),因此虽然 1.0 可能很少出现,但我仍然需要它才能具备这种能力。1.0尽管和之间的差异1.0000001192092895508似乎可以忽略不计(通常是),但在这种情况下,差异很重要。

在实施类似于版本的解决方案后NextAfter,我有时会得到大于最大值的数字(例如5.00000027008353for [0.0,5.0]

Random.NextDouble() * ((NextAfter(max, max + 1.0) - min) + min);

如何生成具有闭合区间的随机浮点数?我将多次执行此操作,因此最好执行不需要太长时间的操作(例如Random多次调用或使用 while 循环和拒绝采样)。此外,必须不偏不倚,产生统一的结果(即,没有任何数字比任何其他数字更可能出现)。

标签: c#randomfloating-pointintervals

解决方案


这看起来很简单:

  • 确定您希望 1.0 平均出现的频率。比如说,十亿分之一。
  • 从钟形分布中生成一个介于 0 到 20 亿之间的随机整数,平均值为 10 亿。称它为 n。
  • 在开区间上生成 n 个随机数。
  • 生成 1.0。
  • 重复。

现在,您在闭合区间上获得了一系列随机数,其中 1.0 平均出现预期次数。你每十亿左右就会得到一个昂贵的钟形计算,它的摊销成本基本上为零。


推荐阅读