PDA

View Full Version : تولید اعداد تصادفی بین دو محدوده



amir_saniyan
یک شنبه 19 اسفند 1386, 12:14 عصر
سلام.

من یک ماکرو به شکل زیر نوشتم که اعداد تصادفی بین min_value و max_value تولید می‌کنه.



/* Returns a random number within a specified range. */
#define AIL_RAND(min_value, max_value) (((float)rand() / (RAND_MAX + 1)) * ((max_value) - (min_value)) + (min_value))


اما مشکل من اینجاست که تو ویژوال استدیو مقدار RAND_MAX عدد 32767 تعریف شده. به همین دلیل دقت این ماکرو برای تولید اعداد تصادفی 1 تقسیم بر 32767 است. مثلا برای اعداد صحیح که 4 بایت هستند خیلی از اعداد تولید نمی‌شوند (مثال زیر):


int x = AIL_RAND(0, 2147483648)

یعنی بین هر دو عدد تصادفی پشت سر هم حداقل 2147483648 تقسیم بر 32767 که می‌شه 65536 فاصله است و امکان نداره فاصله بین دو عدد تصادفی کمتر از 65536 باشه.

حالا برای اینکه مشکل بالا حل بشه و دقت بیشتر، چه کاری می‌شه انجام داد؟ (البته می‌خوام سریع هم باشه)

سپاس

ICEMAN
یک شنبه 19 اسفند 1386, 12:38 عصر
#include <iostream>
using namespace std;

#define MK_RAND( minval, maxval )( minval + rand() % maxval )

int main()
{
for (int i=0; i <= 50; i++)
cout <<MK_RAND( 1, 20 ) <<' ';
return 0;
/*OUTPUT
2 8 15 1 10 5 19 19 3 5 6 6 2 8 2 12 16 3 8 17 12 5 3 14 13 3 2 17 19 16 8 7 12
19 10 13 8 20 16 15 4 12 3 14 14 5 2 12 14 9 8
*/
}

موفق باشید

amir_saniyan
یک شنبه 19 اسفند 1386, 13:04 عصر
ممنون که پاسخ دادید. اما اگه اشتباه نکنم هنوز مشکل حل نشده:

ماکرو شما اینه:

#define MK_RAND( minval, maxval )( minval + rand() % maxval )


حالا کد زیر رو در نظر بگیرید:

int x = MK_RAND(0, 2147483648)

همچنین دقت کنید rand عددی بین 0 تا 32767 تولید می‌کنه.

در این صورت مقدار x به شکل زیر می‌شه:


int x = 0 + {0-32767} % 2147483648

و منظورم از {0-32767} عددی بین 0 تا 32767 است.

بنابراین حداکثر مقداری که x می‌تونه بگیره 32767 می‌باشد!!!!
یعنی x عددی اتفاقی بین 0 تا 32767 است نه عددی اتفاقی بین 0 تا 2147483648 :عصبانی++:

در واقع اساسا مشکل از اینجاست که RAND_MAX یعنی حداکثر عددی که تابع rand تولید می‌کنه از max_value یعنی حداکثر عددی که ما می‌خواهیم کوچکتره

باز هم ممنون از جواب‌تون

ICEMAN
دوشنبه 20 اسفند 1386, 08:15 صبح
شما میخوای از عددی رو که میگیری از 32767 بیشتر باشه !

amir_saniyan
دوشنبه 20 اسفند 1386, 13:10 عصر
شما میخوای از عددی رو که میگیری از 32767 بیشتر باشه !

بله. الان تو برنامم نیاز دارم به همچین عددی. البته می‌شه یک کارایی کرد (مثلا 4 بایت رو نصف کرد، بعد برای دوبایت بالا یک بار رندم و برای دو بایت پایین یکبار دیگه رندم تولید کرد) ولی این کارا هم سریع نیستند و هم مستقل از سکو (Platform)

ICEMAN
دوشنبه 20 اسفند 1386, 14:57 عصر
#include <iostream>
using std:: cout;
using std:: endl;
#include <cstdlib>
using std:: exit;
#include <ctime>
using std:: time;

#define MK_RAND( max ) ((((unsigned int)(((double)rand()/(double)(RAND_MAX+1))*max))*-1)+1);

int main(int argc, char *argv[]){
if(argc != 3)
{
cout <<"Please enter arguments: " <<endl;
cout <<"rand.exe [Max Range] [Count]";
exit(1);
}

long int M = atoi(argv[1]);
int quantity = atoi(argv[2]);

srand(time(NULL));
unsigned int x;
for(int count = 1; count <= quantity; ++count)
{
x= MK_RAND( M );
cout <<count <<"- "<<x << endl;
}
return 0;
}



/*OUTPUT:
CMD> rand.exe 2147483648 10
1- 2087845889
2- 1617952769
3- 249561089
4- 344064001
5- 809107457
6- 2028601345
7- 641597441
8- 927793153
9- 1802633217
10- 1102708737
*/

امیدوارم این کمکت کنه
اگر نه که باید از Library های آماده استفاده کنی