我很惊讶我在任何地方都找不到这个问题的答案,所以也许我遗漏了什么。
NextDouble
System.Random
的方法类返回 [0.0,1.0)
范围内的 double .这是一个返回 0.0 <= x < 1.0
的半开区间.
我需要一个闭区间 [0.0,1.0]
这样 0.0 <= x <= 1.0
.在 C++ 中,我可以使用 std::nextafter
,它返回大于传递参数的最小可表示 float (例如 std::nextafter(1.0, 2.0)
将返回 1.0000001192092895508
)。我似乎找不到 C# 中的等效项。
我正在处理大量高精度数字(16 位),因此尽管 1.0 可能很少出现,但我仍然需要它才能有能力出现。虽然 1.0
之间的区别和 1.0000001192092895508
可能看起来可以忽略不计(而且通常是这样),但在这种情况下差异很重要。
实现类似于 this 的解决方案后NextAfter
的版本, 我有时得到的数字大于最大值(例如 5.00000027008353
为 [0.0,5.0]
)
Random.NextDouble() * ((NextAfter(max, max + 1.0) - min) + min);
如何生成具有闭区间的随机 float ?我将执行这么多次,所以最好是执行时间不会太长的东西(比如多次调用 Random
或使用 while 循环和拒绝采样)。此外,有必要不偏不倚,产生统一的结果(即没有数字比任何其他数字更有可能出现)。
最佳答案
这看起来很简单:
- 确定您希望 1.0 平均出现的频率。比如说,十亿分之一。
- 从钟形分布中生成一个介于 0 到 20 亿之间的随机整数,平均值为 10 亿,您可以选择。称它为 n。
- 在开区间生成 n 个随机数。
- 生成 1.0。
- 重复。
现在您在闭区间上得到了一系列随机数,其中 1.0 平均出现预期次数。您每十亿左右就会进行一次昂贵的钟形计算,分摊到基本上为零成本。
关于C# 随机浮点闭区间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50615404/