简体   繁体   中英

std::normal_distribution<int> runtime error “Integer division by zero”

// 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;

From this code example from cplusplus I get the runtime error "Integer division by zero". The only thing I changed is the type of normal_distribution from double to int and its mean and standard deviation.

Any suggetsions?

The template parameter to std::normal_distribution must be a floating-point type ( float , double , or long double ). Using anything else will result in undefined behavior.

Since normal distribution is a continuous distribution, it isn't really clear what you expect it to do when using an int type. Maybe you can get the result you want by using normal_distribution<double> and rounding the result to int .

You can use binomial_distribution with default probability value of 0.5. link

It will return integer values in range [0,t], with mean at t/2 ( in case t is even else (t+1)/2, (t-1)/2 have equal prob.). You can set the value of t accordingly and shift by adding a constant to the result if needed.

Binomial distribution is discrete approximation of normal distribution ( link ). Normal distributions theoretically have no lower/upper limits.

I prefer to use following thin wrapper over the original:

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;
  }
};

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM