Random Double Issues - c++

I'm having some trouble generating a random double number. I have to create a function that takes no arguments and returns a double (between 0 and 100), the random number. Expect every time I try to create it, it returns a value of 1.
I also have to use a few symbolic constants.
#include <iostream>
#include <iomanip>
#include <ctime>
#include <cstdlib>
double randDouble();
const double UPPER_BOUND = 100.0;
const double LOWER_BOUND = 0.0;
const int ARRAY_SIZE = 100;
double randDouble()
{
int randomInt;
double randomDouble;
srand(time(NULL));
randomInt = rand() % 100 + 1;
randomDouble = LOWER_BOUND + (randomInt / RAND_MAX / ( UPPER_BOUND - LOWER_BOUND));
return randomDouble;
}
int main()
{
cout << randDouble();
return 0;
}
Another thing is, I have to use a pre-given formula for it.
lower bound + ( random integer / (maximum possible random number / (upper bound - lower bound))

First of all, you are not calling randDouble in your main, but try to print the function itself. This will always print 1 or true, depending on whether boolalpha is set. Your compiler would have warned you about that if you had enabled a more aggressive warning level. This is generally recommended.
When you fix this, you will notice that you always get zero. This is because randomInt / RAND_MAX is always zero because of truncating integer division.
When you fix that, you will notice that the returned values are not as desired because your formula is incorrect.
A lot of such problems can be avoided by using the modern std::uniform_real_distribution which already does all the hard work for you.

You can do it in a better and a cleaner way:
#include<random>
#include<iostream>
using namespace std;
int main(){
std::random_device rand_dev;
std::mt19937 gen(rand_dev());
std::uniform_real_distribution<double> dist(0, 100);
// demo.
for(int i = 0; i < 100; ++i){
// call dist(gen) whenever you need a random variable.
cout << dist(gen) << '\n';
}
return 0;
}
This code uses C++11 and won't work on earlier versions.

Related

Generate double random numbers? C++ [duplicate]

How to generate random numbers between two doubles in c++ , these numbers should look like xxxxx,yyyyy .
Here's how
double fRand(double fMin, double fMax)
{
double f = (double)rand() / RAND_MAX;
return fMin + f * (fMax - fMin);
}
Remember to call srand() with a proper seed each time your program starts.
[Edit]
This answer is obsolete since C++ got it's native non-C based random library (see Alessandro Jacopsons answer)
But, this still applies to C
This solution requires C++11 (or TR1).
#include <random>
int main()
{
double lower_bound = 0;
double upper_bound = 10000;
std::uniform_real_distribution<double> unif(lower_bound,upper_bound);
std::default_random_engine re;
double a_random_double = unif(re);
return 0;
}
For more details see John D. Cook's "Random number generation using C++ TR1".
See also Stroustrup's "Random number generation".
This should be performant, thread-safe and flexible enough for many uses:
#include <random>
#include <iostream>
template<typename Numeric, typename Generator = std::mt19937>
Numeric random(Numeric from, Numeric to)
{
thread_local static Generator gen(std::random_device{}());
using dist_type = typename std::conditional
<
std::is_integral<Numeric>::value
, std::uniform_int_distribution<Numeric>
, std::uniform_real_distribution<Numeric>
>::type;
thread_local static dist_type dist;
return dist(gen, typename dist_type::param_type{from, to});
}
int main(int, char*[])
{
for(auto i = 0U; i < 20; ++i)
std::cout << random<double>(0.0, 0.3) << '\n';
}
If accuracy is an issue here you can create random numbers with a finer graduation by randomizing the significant bits.
Let's assume we want to have a double between 0.0 and 1000.0.
On MSVC (12 / Win32) RAND_MAX is 32767 for example.
If you use the common rand()/RAND_MAX scheme your gaps will be as large as
1.0 / 32767.0 * ( 1000.0 - 0.0) = 0.0305 ...
In case of IEE 754 double variables (53 significant bits) and 53 bit randomization the smallest possible randomization gap for the 0 to 1000 problem will be
2^-53 * (1000.0 - 0.0) = 1.110e-13
and therefore significantly lower.
The downside is that 4 rand() calls will be needed to obtain the randomized integral number (assuming a 15 bit RNG).
double random_range (double const range_min, double const range_max)
{
static unsigned long long const mant_mask53(9007199254740991);
static double const i_to_d53(1.0/9007199254740992.0);
unsigned long long const r( (unsigned long long(rand()) | (unsigned long long(rand()) << 15) | (unsigned long long(rand()) << 30) | (unsigned long long(rand()) << 45)) & mant_mask53 );
return range_min + i_to_d53*double(r)*(range_max-range_min);
}
If the number of bits for the mantissa or the RNG is unknown the respective values need to be obtained within the function.
#include <limits>
using namespace std;
double random_range_p (double const range_min, double const range_max)
{
static unsigned long long const num_mant_bits(numeric_limits<double>::digits), ll_one(1),
mant_limit(ll_one << num_mant_bits);
static double const i_to_d(1.0/double(mant_limit));
static size_t num_rand_calls, rng_bits;
if (num_rand_calls == 0 || rng_bits == 0)
{
size_t const rand_max(RAND_MAX), one(1);
while (rand_max > (one << rng_bits))
{
++rng_bits;
}
num_rand_calls = size_t(ceil(double(num_mant_bits)/double(rng_bits)));
}
unsigned long long r(0);
for (size_t i=0; i<num_rand_calls; ++i)
{
r |= (unsigned long long(rand()) << (i*rng_bits));
}
r = r & (mant_limit-ll_one);
return range_min + i_to_d*double(r)*(range_max-range_min);
}
Note: I don't know whether the number of bits for unsigned long long (64 bit) is greater than the number of double mantissa bits (53 bit for IEE 754) on all platforms or not.
It would probably be "smart" to include a check like if (sizeof(unsigned long long)*8 > num_mant_bits) ... if this is not the case.
This snippet is straight from Stroustrup's The C++ Programming Language (4th Edition), §40.7; it requires C++11:
#include <functional>
#include <random>
class Rand_double
{
public:
Rand_double(double low, double high)
:r(std::bind(std::uniform_real_distribution<>(low,high),std::default_random_engine())){}
double operator()(){ return r(); }
private:
std::function<double()> r;
};
#include <iostream>
int main() {
// create the random number generator:
Rand_double rd{0,0.5};
// print 10 random number between 0 and 0.5
for (int i=0;i<10;++i){
std::cout << rd() << ' ';
}
return 0;
}
For generating random numbers we can use the methods that our other friends told. I want to add a very important point here.
The code told by others is :
//I have made this as a function that returns the random double value, just copy this
// if you want
double random(){
return (double)rand() / RAND_MAX; // for generating random points between 0 to 1
}
//now suppose I want any random value between two numbers min and max then I can use this as :
int mynum = min + (max-min)*random();
But the problem with this code is that it is biased, I mean that it is not giving value equally between 0 and 1.
Click here to see the image This image shows how the value returned is more biased towards the center (i.e. is near value one). In order to avoid such condition we should prefer the following code:
double random(){
return sqrt((double)rand() / RAND_MAX); // for generating random points between 0 to 1
}
Reason for choosing Square root function
The reason for choosing sqrt() rather than any other functions like cbrt() to bias it towards the outer end is that in the first approach mentioned above, the points generated were proportional to R^2 because our random was proportional to R, thus making points overall area of the circle proportional to R^2 which made them concentrated more towards the center. Making our random proportional to sqrt(R) would make the points generated over all the area of the circle proportional to R which would make all the points generate uniformly throughout the circle.
Note that after applying sqrt (a point between [0, 1]), the result would be a value greater than the original random() thus making it biased more towards the outer end. This makes the point uniformly generated over all of the circle.
I would like to thank #archit91 for sharing this usefull information on LeetCode in this article
So many great solutions already and many are very elegant. I just figured I would add another to the list. I am drawing references directly from the 'Modern C++ Programming CookBook, 2nd edition'. In the chapter on random number generators, there is some emphasis on how very important it is to properly initialize the pseudo-random number generators. It adds that the Mersenne twister engine has a bias towards producing some values repeatedly and not including other values therefore not generating numbers in a uniform distribution but more like a binomial or Poisson distribution. The snippet I am including goes through the steps of initializing a generator in order to produce pseudo-random numbers with a true uniform distribution.
auto generate_random_double(double lb, double ub)//lb= lowerbound, ub = upperbound
{
//produce random #'s to be used as seeding values
std::random_device rd{};
//Generate random data for all the internal bits of the engine
std::array<double, std::mt19937::state_size> seed_data{};
ranges::generate(seed_data,std::ref(rd));
//Create an std::seed_seq object from the pseudo random data
std::seed_seq seq(std::begin(seed_data), std::end(seed_data));
//Create an engine object and initialize the bits representing the internal
//state of the engine; form example an mt19937 has 19937 bits
auto eng = std::mt19937{ seq };
//Create object based on the approprieat distribution based on application
//requirments
const auto randDouble = std::uniform_real_distribution<>{ lb,ub };
//return object seeded with the previously initialized object
return randDouble(eng);
}//end method generate_random_double
Here's a self-contained C++ class using C++11. It generates a random double within a half-open interval [low, high) (low <= x < high).
#include <random>
// Returns random double in half-open range [low, high).
class UniformRandomDouble
{
std::random_device _rd{};
std::mt19937 _gen{_rd()};
std::uniform_real_distribution<double> _dist;
public:
UniformRandomDouble() {
set(1.0, 10.0);
}
UniformRandomDouble(double low, double high) {
set(low, high);
}
// Update the distribution parameters for half-open range [low, high).
void set(double low, double high) {
std::uniform_real_distribution<double>::param_type param(low, high);
_dist.param(param);
}
double get() {
return _dist(_gen);
}
};
This is similar to my answer above but should work from C++11 and up.
#include <iostream>
#include <random>
#include <array>
#include <algorithm>
#include <functional>
/**
* a function that will generate pseudo random numbers in a normal distribution
* #param lb is the lower bound of the distribution (inclusive)
* #param ub is the upper bound of the distribution (inclusive)
* #return a pseudo random number in the range [lb, ub]
*/
auto generate_random_double(double lb, double ub)
{
std::random_device rd{};
std::array<double, std::mt19937::state_size> seed_data{};
std::generate(seed_data.begin(), seed_data.end(), std::ref(rd));
std::seed_seq seq(std::begin(seed_data), std::end(seed_data));
auto eng = std::mt19937{ seq };
const auto randDouble = std::uniform_real_distribution<>{ lb,ub };
return std::bind(randDouble, eng);
}
something like this:
#include <iostream>
#include <time.h>
using namespace std;
int main()
{
const long max_rand = 1000000L;
double x1 = 12.33, x2 = 34.123, x;
srandom(time(NULL));
x = x1 + ( x2 - x1) * (random() % max_rand) / max_rand;
cout << x1 << " <= " << x << " <= " << x2 << endl;
return 0;
}

How to find value of pi 5 digit by leibniz's series

I am starting to learn C++ and I have a problem with my code. I want to find the pi value using the Leibniz series and also the number of iterations to reach five significant digits (3.14159) but it's doesn't work.
#include<iostream>
#include <math.h>
using namespace std;
int main(){
double pi = 0.0;
int count = 0;
for ( int i = 0 ; i <= 10000 ; i++){
pi += 4*pow(-1,i)/(2*i+1);
if ( pi == 3.14159){
cout<<i;
break;
}
}
}
You may check if the absolute difference between the computed value via Leibniz series and the "true" value of pi is below a given tolerance. Instead of using 3.14159 as value for pi, you may use the built-in constant contained in math.h: M_PI.
#include<iostream>
#include <math.h>
int main(){
double pi = 0.0;
for ( int i = 0 ; i <= 10000 ; i++){
// i-th value via Lieibniz formula
pi += 4*pow(-1,i)/(2*i+1);
// Check if the difference is below a given tolerance equal to 0.0001
if (abs(pi - M_PI)<0.0001){
// Print the iteration at which the given tolerance is achieved
std::cout<<i<< std::endl;
// Break the for cycle
break;
}
}
return 0;
}
The above code checks if the absolute difference between the approximated value and the "true" value of pi is below 0.0001.
You may also check if the relative difference from the actual value is below a given tolerance, by substituting the check with
if (abs(pi - M_PI)/M_PI<0.0001){
// Print the iteration at which the given tolerance is achieved
std::cout<<i<< std::endl;
// Break the for cycle
break;
}
In your code, the variable count is unused. Let me give you a little advice: do not use using namespace::std.

How to generate random double numbers with high precision in C++?

I am trying to generate a number of series of double random numbers with high precision. For example, 0.856365621 (has 9 digits after decimal).
I've found some methods from internet, however, they do generate double random number, but the precision is not as good as I request (only 6 digits after the decimal).
Thus, may I know how to achieve my goal?
In C++11 you can using the <random> header and in this specific example using std::uniform_real_distribution I am able to generate random numbers with more than 6 digits. In order to see set the number of digits that will be printed via std::cout we need to use std::setprecision:
#include <iostream>
#include <random>
#include <iomanip>
int main()
{
std::random_device rd;
std::mt19937 e2(rd());
std::uniform_real_distribution<> dist(1, 10);
for( int i = 0 ; i < 10; ++i )
{
std::cout << std::fixed << std::setprecision(10) << dist(e2) << std::endl ;
}
return 0 ;
}
you can use std::numeric_limits::digits10 to determine the precision available.
std::cout << std::numeric_limits<double>::digits10 << std::endl;
In a typical system, RAND_MAX is 231-1 or something similar to that. So your "precision" from using a method like:L
double r = rand()/RAND_MAX;
would be 1/(2<sup>31</sup)-1 - this should give you 8-9 digits "precision" in the random number. Make sure you print with high enough precision:
cout << r << endl;
will not do. This will work better:
cout << fixed << sprecision(15) << r << endl;
Of course, there are some systems out there with much smaller RAND_MAX, in which case the results may be less "precise" - however, you should still get digits down in the 9-12 range, just that they are more likely to be "samey".
Why not create your value out of multiple calls of the random function instead?
For instance:
const int numDecimals = 9;
double result = 0.0;
double div = 1.0;
double mul = 1.0;
for (int n = 0; n < numDecimals; ++n)
{
int t = rand() % 10;
result += t * mul;
mul *= 10.0;
div /= 10.0;
}
result = result * div;
I would personally try a new implementation of the rand function though or at least multiply with the current time or something..
In my case, I'm using MQL5, a very close derivative of C++ for a specific market, whose only random generator produces a random integer from 0 to 32767 (= (2^15)-1). Far too low precision.
So I've adapted his idea -- randomly generate a string of digits any length I want -- to solve my problem, more reliably (and arguably more randomly also), than anything else I can find or think of. My version builds a string and converts it to a double at the end -- avoids any potential math/rounding errors along the way (because we all know 0.1 + 0.2 != 0.3 😉 )
Posting it here in case it helps anyone.
(Disclaimer: The following is valid MQL5. MQL5 and C++ are very close, but some differences. eg. No RAND_MAX constant (so I've hard-coded the 32767). I'm not entirely sure of all the differences, so there may be C++ syntax errors here. Please adapt accordingly).
const int RAND_MAX_INCL = 32767;
const int RAND_MAX_EXCL = RAND_MAX_INCL + 1;
int iRandomDigit() {
const double dRand = rand()/RAND_MAX_EXCL; // double 0.0 <= dRand < 1.0
return (int)(dRand * 10); // int 0 <= result < 10
};
double dRandom0IncTo1Exc(const int iPrecisionDigits) {
int iPrecisionDigits2 = iPrecisionDigits;
if ( iPrecisionDigits > DBL_DIG ) { // DBL_DIG == "Number of significant decimal digits for double type"
Print("WARNING: Can't generate random number with precision > ", DBL_DIG, ". Adjusted precision to ", DBL_DIG, " accordingly.");
iPrecisionDigits2 = DBL_DIG;
};
string sDigits = "";
for (int i = 0; i < iPrecisionDigits2; i++) {
sDigits += (string)iRandomDigit();
};
const string sResult = "0." + sDigits;
const double dResult = StringToDouble(sResult);
return dResult;
}
Noted in a comment on #MasterPlanMan's answer -- the other answers use more "official" methods designed for the question, from standard library, etc. However, I think conceptually it's a good solution when faced with limitations that the other answers can't address.

Random number between two range

rand() or qrand() functions generate a random int.
int a= rand();
I want to get an random number between 0 and 1.
How I can do this Work?
You can generate a random int into a float, and then divide it by RAND_MAX, like this:
float a = rand(); // you can use qrand here
a /= RAND_MAX;
The result will be in the range from zero to one, inclusive.
Using C++11 you can do the following:
Include the random header:
#include<random>
Define the PRNG and the distribution:
std::default_random_engine generator;
std::uniform_real_distribution<double> distribution(0.0,1.0);
Get the random number
double number = distribution(generator);
In this page and in this page you can find some references about uniform_real_distribution.
Check this post, it shows how to use qrand for your purpose which is afaik a threadsafe wrapper around rand().
#include <QGlobal.h>
#include <QTime>
int QMyClass::randInt(int low, int high)
{
// Random number between low and high
return qrand() % ((high + 1) - low) + low;
}
#include <iostream>
#include <ctime>
using namespace std;
//
// Generate a random number between 0 and 1
// return a uniform number in [0,1].
inline double unifRand()
{
return rand() / double(RAND_MAX);
}
// Reset the random number generator with the system clock.
inline void seed()
{
srand(time(0));
}
int main()
{
seed();
for (int i = 0; i < 20; ++i)
{
cout << unifRand() << endl;
}
return 0;
}
Take a module from the random number which will define the precision. Then do a typecast to float and divide by the module.
float randNum(){
int random = rand() % 1000;
float result = ((float) random) / 1000;
return result;
}

generate random double numbers in c++

How to generate random numbers between two doubles in c++ , these numbers should look like xxxxx,yyyyy .
Here's how
double fRand(double fMin, double fMax)
{
double f = (double)rand() / RAND_MAX;
return fMin + f * (fMax - fMin);
}
Remember to call srand() with a proper seed each time your program starts.
[Edit]
This answer is obsolete since C++ got it's native non-C based random library (see Alessandro Jacopsons answer)
But, this still applies to C
This solution requires C++11 (or TR1).
#include <random>
int main()
{
double lower_bound = 0;
double upper_bound = 10000;
std::uniform_real_distribution<double> unif(lower_bound,upper_bound);
std::default_random_engine re;
double a_random_double = unif(re);
return 0;
}
For more details see John D. Cook's "Random number generation using C++ TR1".
See also Stroustrup's "Random number generation".
This should be performant, thread-safe and flexible enough for many uses:
#include <random>
#include <iostream>
template<typename Numeric, typename Generator = std::mt19937>
Numeric random(Numeric from, Numeric to)
{
thread_local static Generator gen(std::random_device{}());
using dist_type = typename std::conditional
<
std::is_integral<Numeric>::value
, std::uniform_int_distribution<Numeric>
, std::uniform_real_distribution<Numeric>
>::type;
thread_local static dist_type dist;
return dist(gen, typename dist_type::param_type{from, to});
}
int main(int, char*[])
{
for(auto i = 0U; i < 20; ++i)
std::cout << random<double>(0.0, 0.3) << '\n';
}
If accuracy is an issue here you can create random numbers with a finer graduation by randomizing the significant bits.
Let's assume we want to have a double between 0.0 and 1000.0.
On MSVC (12 / Win32) RAND_MAX is 32767 for example.
If you use the common rand()/RAND_MAX scheme your gaps will be as large as
1.0 / 32767.0 * ( 1000.0 - 0.0) = 0.0305 ...
In case of IEE 754 double variables (53 significant bits) and 53 bit randomization the smallest possible randomization gap for the 0 to 1000 problem will be
2^-53 * (1000.0 - 0.0) = 1.110e-13
and therefore significantly lower.
The downside is that 4 rand() calls will be needed to obtain the randomized integral number (assuming a 15 bit RNG).
double random_range (double const range_min, double const range_max)
{
static unsigned long long const mant_mask53(9007199254740991);
static double const i_to_d53(1.0/9007199254740992.0);
unsigned long long const r( (unsigned long long(rand()) | (unsigned long long(rand()) << 15) | (unsigned long long(rand()) << 30) | (unsigned long long(rand()) << 45)) & mant_mask53 );
return range_min + i_to_d53*double(r)*(range_max-range_min);
}
If the number of bits for the mantissa or the RNG is unknown the respective values need to be obtained within the function.
#include <limits>
using namespace std;
double random_range_p (double const range_min, double const range_max)
{
static unsigned long long const num_mant_bits(numeric_limits<double>::digits), ll_one(1),
mant_limit(ll_one << num_mant_bits);
static double const i_to_d(1.0/double(mant_limit));
static size_t num_rand_calls, rng_bits;
if (num_rand_calls == 0 || rng_bits == 0)
{
size_t const rand_max(RAND_MAX), one(1);
while (rand_max > (one << rng_bits))
{
++rng_bits;
}
num_rand_calls = size_t(ceil(double(num_mant_bits)/double(rng_bits)));
}
unsigned long long r(0);
for (size_t i=0; i<num_rand_calls; ++i)
{
r |= (unsigned long long(rand()) << (i*rng_bits));
}
r = r & (mant_limit-ll_one);
return range_min + i_to_d*double(r)*(range_max-range_min);
}
Note: I don't know whether the number of bits for unsigned long long (64 bit) is greater than the number of double mantissa bits (53 bit for IEE 754) on all platforms or not.
It would probably be "smart" to include a check like if (sizeof(unsigned long long)*8 > num_mant_bits) ... if this is not the case.
This snippet is straight from Stroustrup's The C++ Programming Language (4th Edition), §40.7; it requires C++11:
#include <functional>
#include <random>
class Rand_double
{
public:
Rand_double(double low, double high)
:r(std::bind(std::uniform_real_distribution<>(low,high),std::default_random_engine())){}
double operator()(){ return r(); }
private:
std::function<double()> r;
};
#include <iostream>
int main() {
// create the random number generator:
Rand_double rd{0,0.5};
// print 10 random number between 0 and 0.5
for (int i=0;i<10;++i){
std::cout << rd() << ' ';
}
return 0;
}
For generating random numbers we can use the methods that our other friends told. I want to add a very important point here.
The code told by others is :
//I have made this as a function that returns the random double value, just copy this
// if you want
double random(){
return (double)rand() / RAND_MAX; // for generating random points between 0 to 1
}
//now suppose I want any random value between two numbers min and max then I can use this as :
int mynum = min + (max-min)*random();
But the problem with this code is that it is biased, I mean that it is not giving value equally between 0 and 1.
Click here to see the image This image shows how the value returned is more biased towards the center (i.e. is near value one). In order to avoid such condition we should prefer the following code:
double random(){
return sqrt((double)rand() / RAND_MAX); // for generating random points between 0 to 1
}
Reason for choosing Square root function
The reason for choosing sqrt() rather than any other functions like cbrt() to bias it towards the outer end is that in the first approach mentioned above, the points generated were proportional to R^2 because our random was proportional to R, thus making points overall area of the circle proportional to R^2 which made them concentrated more towards the center. Making our random proportional to sqrt(R) would make the points generated over all the area of the circle proportional to R which would make all the points generate uniformly throughout the circle.
Note that after applying sqrt (a point between [0, 1]), the result would be a value greater than the original random() thus making it biased more towards the outer end. This makes the point uniformly generated over all of the circle.
I would like to thank #archit91 for sharing this usefull information on LeetCode in this article
So many great solutions already and many are very elegant. I just figured I would add another to the list. I am drawing references directly from the 'Modern C++ Programming CookBook, 2nd edition'. In the chapter on random number generators, there is some emphasis on how very important it is to properly initialize the pseudo-random number generators. It adds that the Mersenne twister engine has a bias towards producing some values repeatedly and not including other values therefore not generating numbers in a uniform distribution but more like a binomial or Poisson distribution. The snippet I am including goes through the steps of initializing a generator in order to produce pseudo-random numbers with a true uniform distribution.
auto generate_random_double(double lb, double ub)//lb= lowerbound, ub = upperbound
{
//produce random #'s to be used as seeding values
std::random_device rd{};
//Generate random data for all the internal bits of the engine
std::array<double, std::mt19937::state_size> seed_data{};
ranges::generate(seed_data,std::ref(rd));
//Create an std::seed_seq object from the pseudo random data
std::seed_seq seq(std::begin(seed_data), std::end(seed_data));
//Create an engine object and initialize the bits representing the internal
//state of the engine; form example an mt19937 has 19937 bits
auto eng = std::mt19937{ seq };
//Create object based on the approprieat distribution based on application
//requirments
const auto randDouble = std::uniform_real_distribution<>{ lb,ub };
//return object seeded with the previously initialized object
return randDouble(eng);
}//end method generate_random_double
Here's a self-contained C++ class using C++11. It generates a random double within a half-open interval [low, high) (low <= x < high).
#include <random>
// Returns random double in half-open range [low, high).
class UniformRandomDouble
{
std::random_device _rd{};
std::mt19937 _gen{_rd()};
std::uniform_real_distribution<double> _dist;
public:
UniformRandomDouble() {
set(1.0, 10.0);
}
UniformRandomDouble(double low, double high) {
set(low, high);
}
// Update the distribution parameters for half-open range [low, high).
void set(double low, double high) {
std::uniform_real_distribution<double>::param_type param(low, high);
_dist.param(param);
}
double get() {
return _dist(_gen);
}
};
This is similar to my answer above but should work from C++11 and up.
#include <iostream>
#include <random>
#include <array>
#include <algorithm>
#include <functional>
/**
* a function that will generate pseudo random numbers in a normal distribution
* #param lb is the lower bound of the distribution (inclusive)
* #param ub is the upper bound of the distribution (inclusive)
* #return a pseudo random number in the range [lb, ub]
*/
auto generate_random_double(double lb, double ub)
{
std::random_device rd{};
std::array<double, std::mt19937::state_size> seed_data{};
std::generate(seed_data.begin(), seed_data.end(), std::ref(rd));
std::seed_seq seq(std::begin(seed_data), std::end(seed_data));
auto eng = std::mt19937{ seq };
const auto randDouble = std::uniform_real_distribution<>{ lb,ub };
return std::bind(randDouble, eng);
}
something like this:
#include <iostream>
#include <time.h>
using namespace std;
int main()
{
const long max_rand = 1000000L;
double x1 = 12.33, x2 = 34.123, x;
srandom(time(NULL));
x = x1 + ( x2 - x1) * (random() % max_rand) / max_rand;
cout << x1 << " <= " << x << " <= " << x2 << endl;
return 0;
}