std::uniform_real_distribution inclusive range

前端 未结 2 1855
挽巷
挽巷 2020-12-31 19:09

C++11 std::uniform_real_distribution( -1, 1 ) gives numbers in the range [-1,1).

How would you get a uniform real distribution in the range [-1,1]?

Practical

相关标签:
2条回答
  • 2020-12-31 19:22

    Unfortunately the actual implementations of the floating point distributions don't allow you to be so precise. E.g., uniform_real_distribution<float> is supposed to produce values in a given half range, but due to rounding issues it may in fact produce values in an inclusive range instead.

    Here's an example of the problem with generate_cannonical, and similar problems occur with the other real_distributions.

    0 讨论(0)
  • 2020-12-31 19:29

    This is easier to think about if you start by looking at integers. If you pass [-1, 1) you would expect to get -1, 0. Since you want to include 1, you would pass [-1, (1+1)), or [-1, 2). Now you get -1, 0, 1.

    You want to do the same thing, but with doubles:

    Borrowing from this answer:

    #include <cfloat> // DBL_MAX
    #include <cmath> // std::nextafter
    #include <random>
    #include <iostream>
    
    int main()
    {
      const double start = -1.0;
      const double stop = 1.0;
    
      std::random_device rd;
      std::mt19937 gen(rd());
    
      // Note: uniform_real_distribution does [start, stop),
      //   but we want to do [start, stop].
      //   Pass the next largest value instead.
      std::uniform_real_distribution<> dis(start, std::nextafter(stop, DBL_MAX));
    
      for (auto i = 0; i < 100; ++i)
      {
        std::cout << dis(gen) << "\n";
      }
      std::cout << std::endl;
    }
    

    (See the code run here)

    That is, find the next largest double value after the one you want, and pass that as the end value instead.

    0 讨论(0)
提交回复
热议问题