News:

Download Pelles C here: http://www.smorgasbordet.com/pellesc/

Main Menu

Randomizer

Started by Grincheux, March 24, 2021, 03:55:35 PM

Previous topic - Next topic

Grincheux

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:
_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?

John Z

Well I'll give it a try how about this:

RAND_MAX = MAX_EDIT_FIELDS;
srand(_rdtsc());                                   // seed it
_iResult  = (rand() > (RAND_MAX/2) ? rand() :rand() * -1); // +/- 0 to MAX_EDIT_FIELDS


John Z

Grincheux

ok I will test.
Thak You :o

MrBcx

Here's another way ... 


int rnd2 (int _lower, int _upper)
{
   return fmod(rand(),((_upper - _lower+1))) + _lower;
}
Bcx Basic to C/C++ Translator
https://www.bcxbasiccoders.com

Grincheux

fmod(rand(),((MAX_EDIT_FIELDS - -MAX_EDIT_FIELDS+1))) + -MAX_EDIT_FIELDS;
Does not work
_iResult  = (rand() > (RAND_MAX/2) ? rand() :rand() * -1); // +/- 0 to MAX_EDIT_FIELDS
Gives too big numbers
_iResult = MAX_EDIT_FIELDS - rand() % ((2 * MAX_EDIT_FIELDS) + 1);
Give the best results

Thanks to everyone

John Z

#5
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

frankie

Quote from: John Z on March 25, 2021, 12:33:21 AM
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.
"It is better to be hated for what you are than to be loved for what you are not." - Andre Gide

Grincheux

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

John Z

#8
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

frankie

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.

#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;
}
"It is better to be hated for what you are than to be loved for what you are not." - Andre Gide

Grincheux

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

Grincheux


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

frankie

Quote from: Grincheux on March 25, 2021, 04:13:48 PM
Frankie, I seems there is no collision !

Good to hear.
The picture resembles me enough...
"It is better to be hated for what you are than to be loved for what you are not." - Andre Gide