【问题标题】:std::normal_distribution<int> runtime error "Integer division by zero"std::normal_distribution<int> 运行时错误“整数除以零”
【发布时间】:2012-10-18 15:13:00
【问题描述】:
// construct a trivial random generator engine from a time-based seed:
unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();
std::default_random_engine generator (seed);

std::normal_distribution<int> distribution (132,20);

std::cout << "some Normal-distributed results:" << std::endl;
for (int i=0; i<10; ++i)
  std::cout << distribution(generator) << std::endl;

cplusplus 的这个代码示例中,我得到运行时错误“整数除以零”。我唯一改变的是从doubleint 的 normal_distribution 类型及其均值和标准差。

有什么建议吗?

【问题讨论】:

  • 改变了“从到”?像这样的句子有点“意思”,但不是“标准”...... :)
  • 抱歉尖括号吃了我的类型;
  • @DevNoob:您可以将内联代码示例用反引号括起来以避免此类问题。

标签: c++ random std normal-distribution


【解决方案1】:

std::normal_distribution 的模板参数必须是浮点类型(floatdoublelong double)。使用其他任何东西都会导致未定义的行为。

由于正态分布是一个连续分布,因此在使用 int 类型时,您还不清楚您期望它做什么。也许您可以通过使用normal_distribution&lt;double&gt; 并将结果四舍五入到int 来获得您想要的结果。

【讨论】:

  • 当使用 int 类型时,你还不清楚你期望它做什么 - 你可以为任何接受的类型争论,因为它们'最终都是离散的。
【解决方案2】:

您可以使用binomial_distribution,默认概率值为 0.5。 link

它将返回 [0,t] 范围内的整数值,平均值为 t/2(如果 t 偶数为 (t+1)/2,则 (t-1)/2 的概率相等)。您可以相应地设置 t 的值,并在需要时通过在结果中添加一个常数来进行移位。

二项分布是正态分布的离散近似 (link)。理论上,正态分布没有下限/上限。

我更喜欢在原始包装上使用以下薄包装:

template <typename T>
class NormalDistribution {
private:
  std::mt19937 mt;
  std::normal_distribution<T> dis;
public:
  NormalDistribution(T mu, T sigma):dis(mu, sigma) {
    std::random_device rd;
    mt.seed(rd());
  }

  NormalDistribution(T mu, T sigma, unsigned seed ):dis(mu, sigma) {
    mt.seed(seed);
  }

  T random() {
   return dis(mt);
  }
};

template <>
class NormalDistribution<int> {
private:
  std::mt19937 mt;
  std::binomial_distribution<int> dis;
  int _min;
public:
  NormalDistribution(int min, int max):dis(max-min) {
    std::random_device rd;
    mt.seed(rd());
  }

  NormalDistribution(int min, int max, unsigned seed):dis(max-min), _min(min) {
    mt.seed(seed);
  }

  int random() {
   return dis(mt)+_min;
  }
};

【讨论】:

    猜你喜欢
    • 2013-04-06
    • 2015-06-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多