Generate a random double value between -1 and 1

I have been working on this for some time and am experiencing big problems. I want to create a random value from -1 to 1 for calculation. I cannot use the% operator because it is intended only for integers. I also tried using fmod() , but I have difficulties too.

What I tried to use was ...

 double random_value; random_value = fmod((double) rand(),2) + (-1); 

It seems like this is not correct. I also tried to minify time, but I think I'm doing something wrong because it keeps throwing this error:

 "error: expected declaration specifiers or '...' before time" 

code:

 srand((unsigned) time(&t)); 

any help with these problems would be appreciated.

+8
source share
7 answers

This will start the random number generator and give a double value in the range -1.0 to 1.0

 #include <stdio.h> #include <stdlib.h> #include <time.h> int main() { double random_value; srand ( time ( NULL)); random_value = (double)rand()/RAND_MAX*2.0-1.0;//float in range -1 to 1 printf ( "%f\n", random_value); return 0; } 
+6
source

You can sow over time (once before all calls before rand ) as follows:

 #include <time.h> // ... srand (time ( NULL)); 

With this function you can set min / max as needed.

 #include <stdio.h> #include <stdlib.h> /* generate a random floating point number from min to max */ double randfrom(double min, double max) { double range = (max - min); double div = RAND_MAX / range; return min + (rand() / div); } 

Source: [SOLVED] Random dual-generator problem (C programming) in Ubuntu Forums

Then you would call it like this:

 double myRand = randfrom(-1.0, 1.0); 

Note, however, that this will most likely not cover the entire range of precision available with double . Excluding the exponent, the IEEE-754 double contains 52 bits of significance (i.e., the non-exponential part). Since rand returns an int between 0 and RAND_MAX , the maximum possible value of RAND_MAX is INT_MAX . On many (most?) Platforms, int is 32 bits, so INT_MAX is 0x7fffffff , covering 31 bits of the range.

+4
source

I think the best way to create a real random double is to use its structure. Here's an article on how floating point numbers are stored. Since you see that the only limiting condition for float must be from 1 to -1, is that the exponent does not exceed 128.

Ieee754SingleDigits2Double converts the string 0s and 1s to a float variable and returns it. I got this from the answers to this question.

 #include <stdio.h> #include <stdlib.h> #include <time.h> double Ieee754SingleDigits2Double(const char s[32]) { double f; int sign, exp; unsigned int mant; int i; sign = s[0] - '0'; exp = 0; for (i = 1; i <= 8; i++) exp = exp * 2 + (s[i] - '0'); exp -= 127; if (exp > -127) { mant = 1; // The implicit "1." exp -= 23; } else { mant = 0; exp = -126; exp -= 23; } for (i = 9; i <= 31; i++) mant = mant * 2 + (s[i] - '0'); f = mant; while (exp > 0) f *= 2, exp--; while (exp < 0) f /= 2, exp++; if (sign) f = -f; return f; } 

Here's the main function:

 int main(void) { srand ( time ( NULL)); int i; char s[33]; for(i = 0; i < 32; i++) { if(i == 1) continue; s[i] = rand() % 2 + '0'; } s[1] = '0'; s[32] = 0; printf("%s\n", s); printf("%+g\n", Ieee754SingleDigits2Double(s)); return 0; } 
+1
source

Like the other answers, with some improvements, you may need to keep the code more secure and consistent:

 #include <stdlib.h> /* srand and rand */ #include <unistd.h> /* getpid */ #include <time.h> /* time */ #include <errno.h> /* errno */ #include <math.h> /* NAN */ /* generate a float random number in a range */ float randmm(float min, float max) { static int first = -1; if((first = (first<0))) srand(time(NULL)+getpid()); if(min>=max) return errno=EDOM, NAN; return min + (float)rand() / ((float)RAND_MAX / (max - min)); } 

Looking through the code that we have:

  • first static variable that ensures that you do not forget the seeds of a pseudo random number generator (PRNG). The logic is simple and elegant: on the first call, first is -1, then it is compared as less than zero, which updates it to the truth (value 1). The second call asks if first , now 1, is less than zero, which is false (value 0), so srand() not called. The third is a charm, they say, so now the first , which is 0, sets whether it is less than zero, which remains false for this and subsequent iterations.
  • You may then need to ensure that min-max is not zero, otherwise you will get an unpleasant division by zero (or NAN). To do this, we will explicitly call the correct error. Using errno.h set the error and math.h to have a NAN macro (not a number) available. It is impractical to compare two floats for equality (for example, if(min==max) ), so it’s nice to try to invert the min / max values ​​if min is greater, and have a third option if they are equal. Just simplify if you have if only two options: is this correct or not.
  • Finally, I chose to work with float instead of double so as not to trust too much what this function can generate. 32- RAND_MAX an integer (this is RAND_MAX ) can only do a lot. To fill a float reasonable for all bits. float has only 23 bits for the number, plus 8 for the exponent. If you use double you will be misleading and self-confident in the quality of this function. If you need a real double, consider using /dev/urand or another valid true random number generator (TRNG).
  • The last line is just an equation. I think you can easily figure it out. I just like to explicitly use float so that I can see the intent of the code besides interpreting the compiler.
  • And of course, to use whatever OP you want, just call float x = randmm(-1.0, 1.0);
+1
source

This is probably not a good idea, but just because it works, here's the way to generate a random double between -1 and 1 is enabled using /dev/urandom and cos() :

 #include <stdio.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <math.h> int main() { int fd; double x; fd = open("/dev/urandom", O_RDONLY); if (fd == -1) return (1); read(fd, &x, sizeof(x)); close(fd); x = cos(x); printf("%f\n", x); return (0); } 
0
source

After a lot of searching and getting tips around, I create this function to generate a random double number in a certain range.

 #include <stdio.h> #include <stdlib.h> #include <time.h> #include <math.h> double random(double min, double max) { //used it to generate new number each time srand( (unsigned int) time(NULL) ); double randomNumber, range , tempRan, finalRan; //generate random number form 0.0 to 1.0 randomNumber = (double)rand() / (double)RAND_MAX; //total range number from min to max eg. from -2 to 2 is 4 //range used it to pivot form -2 to 2 -> 0 to 4 for next step range = max - min //illustrate randomNumber to range //lets say that rand() generate 0.5 number, thats it the half //of 0.0 to 1.0, show multiple range with randomNumber we get the //half in range. eg 4 * 0.5 = 2 tempRan = randomNumber * range; //add the min to tempRan to get the correct random in ours range //so in ours example we have: 2 + (-2) = 0, thats the half in -2 to 2 finalRan = tempRan + min; return finalRan; } 

This works by illustrating the% random number rate in our range.

0
source
 random_value = (double)rand() * rand() / (RAND_MAX * RAND_MAX) * 2 - 1; 
0
source

Source: https://habr.com/ru/post/1233436/


All Articles