我在c ++中有一个函数,它在两个数字之间返回一个随机浮点数。这是代码:
float randFloatNumBetween(float lower, float upper) {
srand((unsigned)time(NULL));
return lower + ((float) rand() / RAND_MAX) * (upper - lower);
}
当我使用参数调用此函数时,低于0.0且高于10.0,它返回如下数字:
1.00503555
1.01846383
1.03463534
1.05263234
1.06461514
如何让我的函数在逗号前后返回不同的数字?数字如:
5.00503555
3.01846383
1.03463534
4.05263234
8.06461514
答案 0 :(得分:2)
显然,每次调用srand
时都需要更改种子值。根据你留下的评论,这似乎不是你的问题,但需要指出。
一些随机数生成器(我知道Microsoft的rand
是一个)在初始种子和生成的第一个数字之间具有相关性。由于时间变化不是很快,因此播种时得到的数字也会相关。
解决此问题的最佳方法是使用更好的随机数生成器,例如<random>
标头中的C ++ 11生成器:http://en.cppreference.com/w/cpp/numeric/random或升级库中的前任。
否则只需确保在播种后生成几个丢弃的随机数。
答案 1 :(得分:1)
您在每次迭代中调用srand
但srand
should be called only once。将srand((unsigned)time(NULL));
放在此函数之外的文件范围中。
答案 2 :(得分:1)
如果您的编译器支持C ++ 11功能,您可以执行以下操作:
#include <chrono>
#include <random>
#include <iostream>
#include <type_traits>
template<typename T>
typename std::enable_if<std::is_floating_point<T>::value, T>::type randNumBetween(T lower, T upper, std::default_random_engine &gnr) {
if(lower > upper) std::swap(lower, upper);
std::uniform_real_distribution<T> distribution(lower, upper);
return distribution(gnr);
}
template<typename T>
typename std::enable_if<std::is_integral<T>::value, T>::type randNumBetween(T lower, T upper, std::default_random_engine &gnr) {
if(lower > upper) std::swap(lower, upper);
std::uniform_int_distribution<T> distribution(lower, upper);
return distribution(gnr);
}
int main() {
auto seed = std::chrono::system_clock::now().time_since_epoch().count();
std::default_random_engine gnr(seed);
for(auto i(0); i < 10; ++i) std::cout << randNumBetween(10, 20, gnr) << std::endl;
for(auto i(0); i < 10; ++i) std::cout << randNumBetween(10.0, 20.0, gnr) << std::endl;
return 0;
}
在这个不错的video lecture Stephan T. Lavavej解释了为什么使用rand()
被认为是有害且不安全的。