Cách tạo các số ngẫu nhiên giữa hai số đôi trong c ++, những số này phải giống như xxxxx, yyyyy.
Cách tạo các số ngẫu nhiên giữa hai số đôi trong c ++, những số này phải giống như xxxxx, yyyyy.
Câu trả lời:
Đây là cách
double fRand(double fMin, double fMax)
{
double f = (double)rand() / RAND_MAX;
return fMin + f * (fMax - fMin);
}
Hãy nhớ gọi srand () với một hạt giống thích hợp mỗi khi chương trình của bạn bắt đầu.
[Chỉnh sửa] Câu trả lời này đã lỗi thời vì C ++ có thư viện ngẫu nhiên không dựa trên C riêng (xem câu trả lời của Alessandro Jacopsons) Nhưng, điều này vẫn áp dụng cho C
double f = rand() / (RAND_MAX + 1.0);
p(xxxxx,yyyyy)==0.0
Giải pháp này yêu cầu C ++ 11 (hoặc 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;
}
Để biết thêm chi tiết, hãy xem "Tạo số ngẫu nhiên bằng C ++ TR1" của John D. Cook .
Xem thêm "Tạo số ngẫu nhiên" của Stroustrup .
Điều này phải hiệu quả, an toàn và đủ linh hoạt cho nhiều mục đích sử dụng:
#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';
}
Nếu độ chính xác là một vấn đề ở đây, bạn có thể tạo các số ngẫu nhiên với độ phân chia tốt hơn bằng cách ngẫu nhiên hóa các bit quan trọng. Giả sử chúng ta muốn có một nhân đôi giữa 0,0 và 1000,0.
Ví dụ trên MSVC (12 / Win32) RAND_MAX là 32767.
Nếu bạn sử dụng rand()/RAND_MAX
sơ đồ chung, khoảng trống của bạn sẽ lớn bằng
1.0 / 32767.0 * ( 1000.0 - 0.0) = 0.0305 ...
Trong trường hợp IEE 754 biến kép (53 bit quan trọng) và ngẫu nhiên hóa 53 bit, khoảng cách ngẫu nhiên nhỏ nhất có thể có cho bài toán 0 đến 1000 sẽ là
2^-53 * (1000.0 - 0.0) = 1.110e-13
và do đó thấp hơn đáng kể.
Nhược điểm là cần 4 lệnh gọi rand () để nhận số tích phân ngẫu nhiên (giả sử RNG 15 bit).
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);
}
Nếu số bit cho phần định trị hoặc RNG là không xác định, các giá trị tương ứng cần được lấy trong hàm.
#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);
}
Lưu ý: Tôi không biết liệu số lượng bit cho dài dài không dấu (64 bit) có lớn hơn số bit định trị kép (53 bit cho IEE 754) trên tất cả các nền tảng hay không. Có lẽ sẽ là "thông minh" nếu bao gồm một chi phiếu như thế if (sizeof(unsigned long long)*8 > num_mant_bits) ...
này nếu không phải như vậy.
Đoạn mã này là trực tiếp từ Ngôn ngữ lập trình C ++ của Stroustrup (Phiên bản thứ 4) , §40.7; nó yêu cầu 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;
}
một cái gì đó như thế này:
#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;
}