Pelles C forum

C language => Beginner questions => Topic started by: Grincheux on March 24, 2021, 03:55:35 PM

Title: Randomizer
Post by: Grincheux on March 24, 2021, 03:55:35 PM
I would like to generate random numbers between two limits.
It is easy to generate numbers between 0..N
but my problem is to have random numbers between -361 and +361

I have written this but I am not satisfied:
Code: [Select]
_iResult = MAX_EDIT_FIELDS - rand() % ((2 * MAX_EDIT_FIELDS) + 1);
I create a number between 0 and 722 then I substract 361.

Who could help me?
Title: Re: Randomizer
Post by: John Z on March 24, 2021, 05:03:44 PM
Well I'll give it a try how about this:
Code: [Select]
RAND_MAX = MAX_EDIT_FIELDS;
srand(_rdtsc());                                   // seed it
_iResult  = (rand() > (RAND_MAX/2) ? rand() :rand() * -1); // +/- 0 to MAX_EDIT_FIELDS

John Z
Title: Re: Randomizer
Post by: Grincheux on March 24, 2021, 06:18:45 PM
ok I will test.
Thak You :o
Title: Re: Randomizer
Post by: MrBcx on March 24, 2021, 10:34:17 PM
Here's another way ... 
 

int rnd2 (int _lower, int _upper)
 {
   return fmod(rand(),((_upper - _lower+1))) + _lower;
 }
Title: Re: Randomizer
Post by: Grincheux on March 24, 2021, 11:49:13 PM
Code: [Select]
fmod(rand(),((MAX_EDIT_FIELDS - -MAX_EDIT_FIELDS+1))) + -MAX_EDIT_FIELDS;Does not work
Code: [Select]
_iResult  = (rand() > (RAND_MAX/2) ? rand() :rand() * -1); // +/- 0 to MAX_EDIT_FIELDSGives too big numbers
Code: [Select]
_iResult = MAX_EDIT_FIELDS - rand() % ((2 * MAX_EDIT_FIELDS) + 1);Give the best results

Thanks to everyone
Title: Re: Randomizer
Post by: John Z on March 25, 2021, 12:33:21 AM
Hmmmm ... the number can’t be bigger than what RAND_MAX is set to.
I’ll double check.

John Z

Well darn! #undef RAND_MAX, then #define RAND_MAX 0x169 but rand() is ignoring
RAND_MAX.

From book on C
“The function rand() can be used to generate a pseudo-random integer value between 0 and RAND_MAX (0 and RAND_MAX included).”

My sincere apologies for my garbage ‘solution’! A good lesson for me.

John Z
Title: Re: Randomizer
Post by: frankie on March 25, 2021, 12:29:46 PM
Well darn! #undef RAND_MAX, then #define RAND_MAX 0x169 but rand() is ignoring
RAND_MAX.

From book on C
“The function rand() can be used to generate a pseudo-random integer value between 0 and RAND_MAX (0 and RAND_MAX included).”
The symbol RAND_MAX defines the max value that the function 'rand()' can output, isn't a parameter to change to obtain a user range, the max value is compiled in the library function 'rand()' and can't change.
Once again users must not change the system definitions.
Title: Re: Randomizer
Post by: Grincheux on March 25, 2021, 12:46:52 PM
RAND_MAX is equal to 32768 if I have well understood what I read.
In fact it is not possible to create negative numbers.
Funcio ALEA.BETWEEN.xxx in OpenOffice
Title: Re: Randomizer
Post by: John Z on March 25, 2021, 03:00:47 PM
Always learn from ones mistakes.  so revised to be below , but I'm not saying it is better than yours
just different.

MAX_EDIT_FIELDS = 361;
srand(_rdtsc());
_iResult  = (rand() > (RAND_MAX/2) ? (rand() % MAX_EDIT_FIELDS) : -1*(rand() % MAX_EDIT_FIELDS);
corrected typo:
_iResult  = (rand() > (RAND_MAX/2) ? (rand() % MAX_EDIT_FIELDS): -1*(rand() % MAX_EDIT_FIELDS));
----------------
output
-59, -90, 27, -123, 104, -187, 306, 102, 257, -345, 13, -349, -134, 181, 238, -8, 154, -30, 99, -170, 163, -171, 91, 331, -25, 201, 121, -66, 320, 33, -118, -108, -146, -6, 129, 210, 128, 129, -125, -222, 235, -273, 113, -99, -15, 36, 282, -50, 163, -284, -37, -148, -8, 143, 329, -44, -267, 235, -91, 215, 17, 308, -18, 22, -49, -88, -326, -126, 112, -174, 244, -65, 318, 104, 315, -267, -89, 252, -31, -2, -86, -189, -302, 110, 260, 296, 274, -64, 57, -43, 279, 308, -283, 161, -274, -166, -53, 136, -29, -1, -285, 78, 316, 49, -64, 300, 297, 232, -85, -20, -275, 18, 107, -132, 268, 81, 71, -42, -72, 87, 198, -226, -187, 24, 167, 69, 209, -84, -214, 256, -179, 255, -287, -165, 28, -331, 2, -293, -177, 272, -170, 312, 119, -218, 110, 355, 205, -75, -176, 344, -159, -32, -274, 283, 325, -6, -229, -42, -227, -8, -358, 245, -101, 353, 307, -190, -293, -131, -341, -315, 0, 150, 12, -215, -3, -319, 203, -14, 225, 147, 107, -118, 253, 314, -10, -321, -3, 247, -1, 321, 311, 43, 349, 54, -342, 358, 204, 100, 1

John Z
Title: Re: Randomizer
Post by: frankie on March 25, 2021, 03:55:22 PM
rand() returns an integer between 0 and RAND_MAX. The last is maximum value for each implementation (compiler+libraries set).
To obtain what you want with a gaussian distribution you have to use the rand() output adapted to the required range.
In the following snippet the function myrandom(min, max) returns a number inside the range specified by min and max value.
Code: [Select]
#include <stdio.h>
#include <stdlib.h>

#define MIN -361
#define MAX  361

int myrandom(long long int min, long long int max)
{
return (int)(((long long int)rand() / ((long long int)RAND_MAX / (max - min))) + min);
}

int main(int argc, char *argv[])
{
printf ("Sample randomic -361 <==> +361.\n");

for(;;)
{
int r = myrandom(MIN, MAX);
printf("==> %d%s\n", r, ((r<MIN) || (r>MAX)) ? " ==>Error! out of limit!" : "");
}

return 0;
}
Title: Re: Randomizer
Post by: Grincheux on March 25, 2021, 03:59:49 PM
The correct syntax is



srand(_rdtsc());
_iResult  = (rand() > (RAND_MAX/2)) ? (rand() % MAX_EDIT_FIELDS) : -1*(rand() % MAX_EDIT_FIELDS);
                                                   /|\
-----------------------------------------


When looping on 361 values, I have many values that are the same



         GetLocalTime(&_St) ;
         srand(_rdtsc()*_St.wMilliseconds) ;


         _iResult = MAX_EDIT_FIELDS - rand() % ((2 * MAX_EDIT_FIELDS) + 1);


//srand(_rdtsc());
//_iResult  = (rand() > (RAND_MAX/2)) ? (rand() % MAX_EDIT_FIELDS) : -1*(rand() % MAX_EDIT_FIELDS);


I have the same problem but there are fewer collisions.
I think that your problem is that you call many times RAND()


Thank You for your help John
Title: Re: Randomizer
Post by: Grincheux on March 25, 2021, 04:13:48 PM

Frankie, I seems there is no collision !
return (int)(((long long int)rand() / ((long long int)RAND_MAX / (max - min))) + min);


return (int)(((long long int)rand() / ((long long int)RAND_MAX / (361 - -361))) + -361);
return (int)(((long long int)rand() / ((long long int)RAND_MAX / (361 + 361))) - 361);
return (int)(((long long int)rand() / ((long long int)RAND_MAX / 722)) - 361);


YOU ARE THE BEST
Title: Re: Randomizer
Post by: frankie on March 25, 2021, 04:44:41 PM
Frankie, I seems there is no collision !

Good to hear.
The picture resembles me enough...