boost::random 和 boost:uniform_real 适用于双精度而不适用于浮点数?

发布于 2024-11-17 04:34:16 字数 1040 浏览 3 评论 0原文

如果已经讨论过这个问题,请原谅我。我有一个模板函数,它根据模板参数使用 boost::uniform_int 和 boost::uniform_real ,并且应该返回相同的类型:

template <typename N> N getRandom(int min, int max)
{
  timeval t;
  gettimeofday(&t,NULL);
  boost::mt19937 seed((int)t.tv_sec);
  boost::uniform_int<> dist(min, max);
  boost::variate_generator<boost::mt19937&, boost::uniform_int<> > random(seed, dist);
  return random(); 
}
//! partial specialization for real numbers
template <typename N> N getRandom(N min, N max)
{
  timeval t;
  gettimeofday(&t,NULL);
  boost::mt19937 seed( (int)t.tv_sec );
  boost::uniform_real<> dist(min,max);
  boost::variate_generator<boost::mt19937&, boost::uniform_real<> > random(seed,dist);
  return random(); 
}

现在我已经用 int、float 和 double 测试了该函数。 它适用于 int,适用于 double,但不适用于 float。就好像它要么将 float 转换为 int,要么存在一些转换问题。我这么说的原因是因为当我这样做时:

float y = getRandom<float>(0.0,5.0);

我总是得到一个 int 返回。 然而,就像我说的,它适用于双打。 我做错了什么或遗漏了什么吗? 谢谢 !

Pardon me if this has been discussed already. I've got a template function which uses boost::uniform_int and boost::uniform_real depending on the template argument and should return the same type:

template <typename N> N getRandom(int min, int max)
{
  timeval t;
  gettimeofday(&t,NULL);
  boost::mt19937 seed((int)t.tv_sec);
  boost::uniform_int<> dist(min, max);
  boost::variate_generator<boost::mt19937&, boost::uniform_int<> > random(seed, dist);
  return random(); 
}
//! partial specialization for real numbers
template <typename N> N getRandom(N min, N max)
{
  timeval t;
  gettimeofday(&t,NULL);
  boost::mt19937 seed( (int)t.tv_sec );
  boost::uniform_real<> dist(min,max);
  boost::variate_generator<boost::mt19937&, boost::uniform_real<> > random(seed,dist);
  return random(); 
}

Now I've tested the function with int, float and doubles.
It works fine with int, it works fine with double, but it does not work with floats. It's as if it either translates a float as an int, or there is some casting problem. Reason I'm saying this is because when i do:

float y = getRandom<float>(0.0,5.0);

I always get an int back.
However, like I said, it works with doubles.
Is there something I'm doing wrong or missing ?
Thank you !

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

李不 2024-11-24 04:34:16

参数 0.0,5.0 是双精度数,而不是浮点数。让它们漂浮:

float y = getRandom<float>(0.0f,5.0f);

The arguments 0.0,5.0 are doubles, not floats. Make them floats:

float y = getRandom<float>(0.0f,5.0f);
转身泪倾城 2024-11-24 04:34:16

您甚至可以避免编写具有类型特征和 MPL 的样板代码:

template <typename N>
N getRandom(N min, N max)
{
  typedef typename boost::mpl::if_<
    boost::is_floating_point<N>, // if we have a floating point type
    boost::uniform_real<>,       // use this, or
    boost::uniform_int<>         // else use this one
  >::type distro_type;

  timeval t;
  gettimeofday(&t,NULL);
  boost::mt19937 seed( (int)t.tv_sec );
  distro_type dist(min,max);
  boost::variate_generator<boost::mt19937&, distro_type > random(seed,dist);
  return random(); 
};

You can even avoid writing boilerplate code with type traits and MPL:

template <typename N>
N getRandom(N min, N max)
{
  typedef typename boost::mpl::if_<
    boost::is_floating_point<N>, // if we have a floating point type
    boost::uniform_real<>,       // use this, or
    boost::uniform_int<>         // else use this one
  >::type distro_type;

  timeval t;
  gettimeofday(&t,NULL);
  boost::mt19937 seed( (int)t.tv_sec );
  distro_type dist(min,max);
  boost::variate_generator<boost::mt19937&, distro_type > random(seed,dist);
  return random(); 
};
梦在深巷 2024-11-24 04:34:16

本身并没有真正解决您的问题,而是解决方案:

为什么不使用特征类来获得正确的分布类型?

template<class T>
struct distribution
{ // general case, assuming T is of integral type
  typedef boost::uniform_int<> type;
};

template<>
struct distribution<float>
{ // float case
  typedef boost::uniform_real<> type;
};

template<>
struct distribution<double>
{ // double case
  typedef boost::uniform_real<> type;
};

有了这一组,您就可以拥有一个通用功能:

template <typename N> N getRandom(N min, N max)
{
  typedef typename distribution<N>::type distro_type;

  timeval t;
  gettimeofday(&t,NULL);
  boost::mt19937 seed( (int)t.tv_sec );
  distro_type dist(min,max);
  boost::variate_generator<boost::mt19937&, distro_type > random(seed,dist);
  return random(); 
};

Not really addressing your question per se, but a solution:

Why not use a traits class to get the right distribution type?

template<class T>
struct distribution
{ // general case, assuming T is of integral type
  typedef boost::uniform_int<> type;
};

template<>
struct distribution<float>
{ // float case
  typedef boost::uniform_real<> type;
};

template<>
struct distribution<double>
{ // double case
  typedef boost::uniform_real<> type;
};

With that set, you can have one general function:

template <typename N> N getRandom(N min, N max)
{
  typedef typename distribution<N>::type distro_type;

  timeval t;
  gettimeofday(&t,NULL);
  boost::mt19937 seed( (int)t.tv_sec );
  distro_type dist(min,max);
  boost::variate_generator<boost::mt19937&, distro_type > random(seed,dist);
  return random(); 
};
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文