我想收集在一个地方在所有四种类型的间隔上生成随机数的“最佳”方式。我厌倦了谷歌搜索。搜索结果出现了很多废话。甚至相关的结果也是页面或博客,这些页面或博客通常是完全错误的,或者在讨论中自封的专家在某些技术上存在分歧,通常他们的“答案”似乎暴露了他们不了解不同的类型(关闭、开、半开)的区间。对于这样一个“简单”的问题,我厌倦了阅读有关在 C 中生成随机数的不良信息。
请告诉我如何生成均匀分布的浮点数。这是我在 (a,b)、[a,b)、(a,b] 和 [a,b] 上的典型方式(以“long double”为例):
long double a=VALUE1,b=VALUE2;
long double x1,x2,x3,x4;
srand((unsigned)time(NULL));
/* x1 will be an element of [a,b] */
x1=((long double)rand()/RAND_MAX)*(b-a) + a;
/* x2 will be an element of [a,b) */
x2=((long double)rand()/((long double)RAND_MAX+1))*(b-a) + a;
/* x3 will be an element of (a,b] */
x3=(((long double)rand()+1)/((long double)RAND_MAX+1))*(b-a) + a;
/* x4 will be an element of (a,b) */
x4=(((long double)rand()+1)/((long double)RAND_MAX+2))*(b-a) + a;
对于单位区间 (0,1)、[0,1)、(0,1] 和 [0,1] 的特殊情况:
long double x1,x2,x3,x4;
srand((unsigned)time(NULL));
/* x1 will be an element of [0,1] */
x1=((long double)rand()/RAND_MAX);
/* x2 will be an element of [0,1) */
x2=((long double)rand()/((long double)RAND_MAX+1));
/* x3 will be an element of (0,1] */
x3=(((long double)rand()+1)/((long double)RAND_MAX+1));
/* x4 will be an element of (0,1) */
x4=(((long double)rand()+1)/((long double)RAND_MAX+2));
我相信对 RAND_MAX 和 rand() 的返回值的强制转换都是必要的,不仅因为我们想要避免整数除法,而且因为它们是整数,否则添加一个(或两个)可能会使它们溢出。
我认为“double”和“float”的版本完全相同,只是替换了类型。不同的浮点类型是否有任何微妙之处?
您发现上述实现有什么问题吗?如果是这样,您将如何解决它以及如何解决它?
编辑:上述实现通过了必要的测试以使其正确(至少在运行 64 位 Linux 的 64 位 Intel Core 2 Duo 机器上):x1 可以生成 0 和 1,x2 可以生成 0 但还没有看到生成 1,x3 可以生成 1,但尚未看到生成 0,并且未看到 x4 生成 0 或 1。