Як генерувати випадкові числа між двома подвійними в c ++, ці числа повинні мати вигляд xxxxx, yyyyy.
Як генерувати випадкові числа між двома подвійними в c ++, ці числа повинні мати вигляд xxxxx, yyyyy.
Відповіді:
Ось як
double fRand(double fMin, double fMax)
{
double f = (double)rand() / RAND_MAX;
return fMin + f * (fMax - fMin);
}
Не забувайте викликати srand () із відповідним початковим елементом кожного разу, коли запускається ваша програма.
[Редагувати] Ця відповідь застаріла, оскільки C ++ отримав власну випадкову бібліотеку, що не базується на C (див. Відповідь Алессандро Якопсона) Але, це все ще стосується C
double f = rand() / (RAND_MAX + 1.0);
p(xxxxx,yyyyy)==0.0
Для цього рішення потрібен C ++ 11 (або 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;
}
Детальніше див. У статті Джона Д. Кука "Виробництво випадкових чисел за допомогою C ++ TR1" .
Див. Також "Створення генератора випадкових чисел" .
Це повинно бути продуктивним, безпечним для потоків і досить гнучким для багатьох цілей:
#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';
}
Якщо точність тут проблема, ви можете створити випадкові числа з точнішим градуюванням шляхом рандомізації значущих бітів. Припустимо, ми хочемо мати подвійне значення від 0,0 до 1000,0.
Наприклад, на MSVC (12 / Win32) RAND_MAX дорівнює 32767.
Якщо ви використовуєте загальну rand()/RAND_MAXсхему, ваші прогалини будуть настільки великими, як
1.0 / 32767.0 * ( 1000.0 - 0.0) = 0.0305 ...
У випадку подвійних змінних IEE 754 (53 значущих біта) та 53-бітової рандомізації, найменший можливий інтервал рандомізації для задачі від 0 до 1000 буде
2^-53 * (1000.0 - 0.0) = 1.110e-13
а отже суттєво нижчий.
Недоліком є те, що для отримання рандомізованого цілого числа (припускаючи 15-бітний RNG) буде потрібно 4 виклики rand ().
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);
}
Якщо кількість бітів для мантиси або RNG невідома, відповідні значення потрібно отримати в межах функції.
#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);
}
Примітка: Я не знаю, чи перевищує кількість бітів для long unsigned long (64 біт), ніж кількість бітів подвійної мантиси (53 біта для IEE 754) на всіх платформах чи ні. Можливо, було б «розумно» включити чек, if (sizeof(unsigned long long)*8 > num_mant_bits) ...якби це не так.
Цей фрагмент безпосередньо наведено в мові програмування C ++ від Stroustrup (4th Edition) , §40.7; для цього потрібен 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;
}
щось на зразок цього:
#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;
}