函数返回所有相同的随机数

时间:2014-06-18 18:16:26

标签: c++ random

我在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

3 个答案:

答案 0 :(得分:2)

显然,每次调用srand时都需要更改种子值。根据你留下的评论,这似乎不是你的问题,但需要指出。

一些随机数生成器(我知道Microsoft的rand是一个)在初始种子和生成的第一个数字之间具有相关性。由于时间变化不是很快,因此播种时得到的数字也会相关。

解决此问题的最佳方法是使用更好的随机数生成器,例如<random>标头中的C ++ 11生成器:http://en.cppreference.com/w/cpp/numeric/random或升级库中的前任。

否则只需确保在播种后生成几个丢弃的随机数。

答案 1 :(得分:1)

您在每次迭代中调用srandsrand 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;
}

DEMO

在这个不错的video lecture Stephan T. Lavavej解释了为什么使用rand()被认为是有害且不安全的。