Generating a random, uniformly distributed real number in C [duplicate] - c

This question already has answers here:
Generate random double number in range [0, 1] in C
(2 answers)
Closed 2 years ago.
I would like to generate a random, real number in the interval [0,1].
I would like to set a pointer, say n, for the number so whenever I stated n, it will be referred to the random generated number.
I have searched on StackOverflow and on Google, but most of them are for C++ or for integers.
I have tried this code suggested to me in the answers:
#include <stdio.h>
#include <stdlib.h>
int main()
{
double n;
double get_random() { return (double)rand() / (double)RAND_MAX; }
n = get_random();
printf("%f", n);
return 0;
}
However, I can only get a value 0.00000000.
How could I fix my program?

You can use:
#include <time.h>
srand(time(NULL)); // randomize seed
double get_random() { return (double)rand() / (double)RAND_MAX; }
n = get_random();
srand() sets the seed which is used by rand to generate pseudo-random numbers. If you don't call srand before your first call to rand, it's as if you had called srand(1) (serves as a default).
If you want to exclude [1] use:
(double)rand() / (double)((unsigned)RAND_MAX + 1);
Full solution:
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
double get_random() { return ((double)rand() / (double)RAND_MAX); }
int main()
{
double n = 0;
srand(time(NULL)); // randomize seed
n = get_random(); // call the function to get a different value of n every time
printf("%f\n", n); // print your number
return 0;
}
Every time you run it you will get a different number for n.

This shows how to get random real numbers in the range 0..1 but please note that they are not uniformly distributed. There are only (RAND_MAX+1) discrete values.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(void) {
int i;
double n;
srand((unsigned)time(NULL)); // seed the random num generator ONCE only
for(i = 0; i < 3; i++) { // get 3 random numbers
n = (double)rand() / RAND_MAX; // in the range 0 ... 1
printf("%f\n", n); // use correct format specifier for the var
}
return 0;
}
My program output:
0.622608
0.814081
0.878689

Related

Error with rand() function: same numbers into a for loop

I have a problem with the rand() function. I would like to randomly generate eps values, different one from each other for i=0,...,VOL.
However, when I print eps, it is always the same.
Could you please tell what it is wrong in my code? Thank you.
...
#include <time.h>
...
void function(...);
int main(){
function();
return 0;
}
void function(...){
srand((unsigned int)time(NULL));
...
for(i=0;i<VOL;i++){
signal1[i]=0.; // No signal
eps=rand()/(RAND_MAX+0.5);
if(signal1[i]==(MIN+MAX)){
net[i]= 0;
exp[i]=a+eps;
printf("eps: %f\n", eps);
}
}
}
The full part of the code (to copy the entire code is impossible as it is very long) is:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#define VOL 15
#define MAX 10
#define MIN 0
float random_sign_high[VOL]={2,2,2,2,2,2,2,2,2,1,1,1,1,1,0};
float random_sign_low[VOL]={2,2,2,2,2,2,2,2,1,1,1,1,1,0,0};
void function();
int main(){
function();
return 0;
}
void function(){
...
srand((unsigned int)time(NULL));
for(i=0;i<VOL;i++){
signal1[i]=0.; // No signal
signal2[i]=0.; // No signal
if(H_PR!=0){
shuffle_signals(random_sign_high);
}
if(L_PR!=0){
shuffle_signals(random_sign_low);
}
eps=rand()/(RAND_MAX+0.5);
printf("eps: %f\n", eps);
if(tot_sig==(MIN+MAX)){
net[i]= 0;
exp_p[i]=a+eps;
}
and the shuffle function is:
double shuffle_signals(float array[VOL])
{
srand((unsigned int) time(NULL));
if(VOL>1)
{
int i,j,t;
for(i=0; i<VOL;i++)
{
j=i+rand()/((float)RAND_MAX/(VOL-i)+1.);
t=array[j];
array[j]=array[i];
array[i]=t;
if(array[i]==1){
signal2[i]=MIN;
signal1[i]=MAX;
}
else if(array[i]==0){
signal2[i]=MIN;
signal1[i]=MIN;
}
else if (array[i]==2){
signal1[i]=MAX;
signal2[i]=MAX;
}
tot_sig= signal1[i]+signal2[i];
}
// printf("tot_sign: %lf\n", tot_sig);
}
return tot_sig;
}
}
The other parts are irrelevant. You can think 'a' be a constant, H_PR=0.5 and L_PR=0.1
Thanks a lot.
You're calling shuffle_signals() repeatedly from inside a loop. Each time you visit this function, you call srand(), which resets the random number generator based on the current time (seconds since 1970). You should only call srand() once in your program. Somewhere near the top of main() would be a good place to do it.
the function: shuffle_signals() is recursive, However, the function: srand() should be called only once in the whole program. Suggest moving the call to srand() to early in the main() function.
You can do that:
int main ()
{
int x;
x = rand() % 100; // here you got always the same value
printf ("Our first number: %d\n", x);
srand ( time(NULL) ); // from now on you'll get random values
x = rand() % 100;
printf ("Some random number: %d\n", x);
x = rand() % 100;
printf ("The first number again: %d\n", x);
return 0;
}
There's nothing affects random values in when adding unsigned int in srand(unsigned int(time(NULL))) so you can add it or leave it the result is ok.

Generate a random double between -1 and 1

I've been working on this for some time and having a lot of trouble. I want to generate a random value from -1 to 1 for a calculation. I cant use the % operator because it is for integers only. I also tried using fmod() but I'm having difficulty here too.
What I was trying to use was...
double random_value;
random_value = fmod((double) rand(),2) + (-1);
it seems like it's not correct though. I also tried to seed srand with the time, but I think im doing something wrong there 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 appreciate.
You can seed with time (once before all calls to rand) like this:
#include <time.h>
// ...
srand (time ( NULL));
With this function you can set the 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 double generator problem (C Programming) at Ubuntu Forums
Then you would call it like this:
double myRand = randfrom(-1.0, 1.0);
Note, however, that this most likely won't cover the full range of precision available from a double. Without even considering the exponent, an IEEE-754 double contains 52 bits of significand (i.e. the non-exponent 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 range.
This will seed the random number generator and give a double in the range of -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;
}
I think the best way to create a real random double is to use its structure. Here's an article about how float numbers are stored. As you see the only limiting condition for float to be between 1 and -1 is that the exponent value doesn't exceed 128.
Ieee754SingleDigits2Double converts string of 0s and 1s to a float variable and return it. I got it 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;
}
Probably not a good idea to do so, but just because it works, here's a way of generating a random double between -1 and 1 included 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);
}
Similar to other answers, with a few improvements you might need to keep your code a bit safer and coherent:
#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));
}
Going through the code we have:
A static variable first that will guarantee you don't forget to seed the pseudo-random number generator (PRNG). The logic is simple and elegant: in the first call, first is -1, it is then compared to be less than zero, which updates it to true (value 1). The second call asks if first, now 1, is less than zero, which is false (value 0), so srand() isn't called. Third is a charm, they say, so now first, which is 0, is asked if it is less than zero, which keeps being false for this and the next iterations.
Next, you might need to guarantee that min-max is not zero, or else you will get a nasty division by zero (or NAN). For that we shall explicitly cause the correct error. Using errno.h to set the error and math.h to have NAN (not a number) macro available. It is not advisable to compare two floats for equality (like if(min==max)) so it is not a good idea to try to invert the min/max values in case min is greater, and have a third option in case they are equal. Just simplify your if with only two options: it is right, or it is not.
Finally, I've preferred to work with float instead of double to not give too much trust on what this function can generate. A 32 bits integer (which is RAND_MAX) can only do so much. To fill a float is reasonable, for all bits. float has only 23 bits for the number, plus 8 for exponent. If you use double you will be mislead and overconfident in the capacity of this function. If you need a true double, consider using /dev/urand or other proper true random number generator (TRNG).
The last line, the return, is just a simple equation. I guess you can figure that out easily. I just like to explicitly cast to float so I can see the code's intention besides the compiler's interpretation.
And of course, to use as OP want, just call as float x = randmm(-1.0, 1.0);
This answer mostly applies to people looking for random doubles on x86_64 machines.
Being a long time C user (since late 1980s), I gave up caring what the RAND_MAX value of the day is.
Also, the srand(time(NULL) indicates to me that the numbers are generated with some quasi random number generator of (at least to me) unknown quality. And all that, while you are just 1 assembly instruction away from CPU random numbers on modern x86_64 machines.
So, the code below uses rdrand via intrinsics, which is known to be a full 64bit random number as a source of randomness. This way, at least, you have sufficient bits to generate a double without further ado. If - instead - you opted for C library rand() and it returned a 32 bit value, you might have not enough bits for a 64 floating point number. And there is no randl(), randul() or alike in Ansi C, afaik.
But - if you look at the signature of the _rdrand_step() intrinsic, it seems like this instruction might fail under certain conditions. (Load related, some say). So, in the code below, it might (or might not) be a good idea to write a while() loop or something like that around the intrinsic call.
#include <stdio.h>
#include <stdint.h>
#include <immintrin.h>
#include <float.h>
int randomf64(double minVal, double maxVal, double* out) {
if (NULL == out)
return 0;
uint64_t result = 0ULL;
// cast in next line works for amd64 (x86_64) on linux at least.
int rc = _rdrand64_step((unsigned long long*)&result);
if(rc) {
double unscaled = (double)result/(double)UINT64_MAX;
*out = minVal + (maxVal - minVal) * unscaled;
return 1;
}
return 0;
}
int main(int argc, const char* argv[]) {
size_t nvals = 1;
if(argc > 1) {
nvals = atol(argv[1]);
}
// We want to see if all that "can fail under stress" thing happens...
double *values = malloc(nvals * sizeof(double));
if (NULL != values) {
for(size_t i = 0; i < nvals; ++i ) {
if(!randomf64(-100.0,100.0, &values[i])) {
printf("boom! after %lu random numbers generated.\n",
i);
free(values);
exit(-1);
}
}
for(size_t i = 0; i < nvals; ++i) {
int Digs = DECIMAL_DIG;
printf("%lu %.*e\n", i, Digs, values[i]);
}
free(values);
}
return 0;
}
If you supply an integer as a command line argument, it generates a respective
number of random doubles and stores them in a heap allocated array.
This allows for testing if that "sporadic failing" might happen. I tried several times with up to 1E6 values created in a burst and it never failed (on some cheap AMD CPU).
In order to compile this, e.g. with clang, I used:
clang -mrdrnd -O3 -std=c17 -o r64i r64intrin.c
Please note, that you have to enable the usage of the intrinsic with -mrdrnd for the compiler to be happy.
For higher precision:
double random() {
unsigned int rnd;
rnd = (rand() & 0x7fff) | ((rand() & 0x7fff) << 15);
return (double)rnd / (double)(0x3fffffff);
}
Of course it would be possible to add a full 32 bit precision or even a long precision to this. But RAND_MAx is as someone stated 15bits, and would need more calls to rand() and then 'or' them together in a similar fashion.
There are a lot of rand(min, max) solutions here, so I won't comment on that. If you need full range random double (from lowest possible to highest possible):
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
// full range uint32_t rand - from 0 to UINT32_MAX
uint32_t rand32() {
// in in mingw32 RANDMAX is 32767
#if RAND_MAX < 32768
union {
uint16_t i[2];
uint32_t l;
} n;
uint16_t t; // we need two more bits
n.i[0] = rand(); // first 16 bits
n.i[1] = rand(); // last 16 bits
t = rand();
if ((t & 0x01) != 0) { // add the MSbit
n.i[0] |= 0x8000;
}
if ((t & 0x02) != 0) { // add the MSbit
n.i[1] |= 0x8000;
}
return n.l;
#else
// USUALLY RAND_MAX is 2147483647 (or 0x7FFFFFFF) - missing the MSbit
uint32_t l;
uint32_t t;
l = rand();
t = rand();
if ((t & 0x01) != 0) { // add the MSbit
l |= 0x80000000;
}
return l;
#endif
}
// full range random double
double randDouble() {
union {
uint32_t i[2];
double d;
} num;
num.i[0] = rand32();
num.i[1] = rand32();
return num.d;
}
int main(int argc, char *argv[]) {
time_t result = time(NULL);
srand(result);
printf("random uint32: %0x08X\n", rand32());
// up to 200 digits after the decimal point. Sometimes the number is really small
printf("random double: %lE\n", randDouble());
}
After search a lot to this and getting tips from around, i create this function to generate random double number in specific 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 is working illustrating the rate % of random number in ours range.
random_value = (double)rand() * rand() / (RAND_MAX * RAND_MAX) * 2 - 1;
There is an easy way to get random value in range [-1.0; 1.0] Trigonometric function sine takes a number returned by rand() and returns value in that range.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
/* macro returning value in range [-1.0; 1.0] */
#define double_rand() ( sin(rand()) )
int main(void) {
int i;
srand(time(NULL));
/* 20 tests to show result */
for ( i = 0; i < 20; ++i )
printf("%f\n", double_rand());
return 0;
}
On linux systems don't forget to link the math library
$ gcc -Wall sin_rand.c -lm
$ ./a.out
0.014475
-0.751095
-0.650722
0.995111
-0.923760
...

Random number in for loop C

I need to generate 1000 random numbers inside a for loop.
my problem is that the random number generated is always the same. since im using time NULL to initiate the generator, why am i getting the same numbers? here is the code i used:
#include <stdio.h>
#include <stdlib.h>
#define LIMIT 30000
int main(){
int i;
srand((long) time(NULL));
for(i = 0; i < 1000; i++){
int x = rand() % LIMIT;
printf("%d\n", x);
}
}
If you run the program multiple times during the same second, you will pass the same value to the generator as seed. You have to wait at least a second before trying it again.
This is because the time function returns the number of seconds since a specific time, and if called multiple times during the same second will return the same value.
your code is right, but you forgot to include the time.h library.
#include <stdio.h>
#include <stdlib.h>
#include <time.h> // <--- now it works
#define LIMIT 30000
int main(){
int i;
srand((long) time(NULL));
for(i=0;i<1000;i++){
int x = rand() % LIMIT;
printf("%d",x);}

c random number on time

Why does this program only generate numbers from 0.1-0.2. It needs to generate numbers from 0-1.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main (int argc, char *argv[])
{
/*declare pseudo-random number */
float random;
srand(time(NULL));
random = (float) rand() / (float) RAND_MAX;
printf("The random number is %f\n", random);
return 0;
}
I'm compiling using gcc on a mac.
The code seems fine to me. Try to generate more than one number and see then:
for(i=1; i<100; i++){
random = (float) rand() / (float) RAND_MAX;
printf("%f\n", random);
}
int random_seed;
void __cdecl srand(int data){
random_seed = data;
}
int __cdecl rand (
void
)
{
return( ((random_seed = random_seed * 214013L
+ 2531011L) >> 16) & 0x7fff );
}
This is the implementation of srand() and rand() on windows CRT. I am not sure if I will be sued by MS for this.
Clearly, you might have to call rand() many times to get a proper value between 0 and 1. no matter what time() returns[as it will only be set into random_seed].
The above code went fine for me(gcc in ubuntu) i.e. my output was varying from 0.1 to 1. Try to run the program three-four times an then see the output

Storing a Randomly generated number in a variable

Im trying to make a program that calculates out a math equation, Im getting stuck on how i generate a random number from 0.00 to 1.00 and store it in a variable a.
this is my code so far, im stuck to how now take that number and store it for future use. I need to store that random number in a, and hten use it in a loop, and then generate a new random number and use it in the 2nd cycle of the loop.
EDIT
this is what i have been working on now, it is suppose to calculate the number of times a random number is inside the area, count it, and then devide by the number of times run, but im not getting any output
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
void initrand(void)
{
srand(time(0));
}
float randfloat(void)
{
return rand()/(float)RAND_MAX;
}
int main(void)
{
int n = 10;
float x;
float y;
float pi = 3.1415;
float rootxy;
initrand();
int z = 0;
int inside = 0;
x = randfloat();
y = randfloat();
float area = 0.25 * pi;
float calculatedpi;
rootxy = sqrt(pow(x,2) + (pow(y,2)));
while (z < n){
if (rootxy > area) {
inside++;
z++;
}
else{
return 0;
}
calculatedpi = (inside/n);
}
printf("%f", calculatedpi);
}
There are a few issues with your code:
You shouldn't use nested functions. Some compilers support them as an extension but it's not standard. Define randfloat and initrand outside main
The function initrand does too little. Why not call srand((time(0)); from main ?
Your initrand function is declared as returning a double but it doesn't return anything (and the way it's named it shouldn't). If you need to use such a function, why not make it return void ?
You should rarely use float. Why not use double ?
That said, you can do this to store that random value:
double randdouble()
{
return rand()/((double)RAND_MAX + 1);
}
int main()
{
double x = randdouble();
/* ... */
}
I think you want something like this:
#include <stdlib.h>
#include <time.h>
void initrand(void)
{
srand(time(0));
}
float randfloat(void)
{
return rand()/(float)RAND_MAX;
}
int main(void)
{
initrand();
float a = randfloat();
return 0;
}
You can't nest functions like in some other languages.
You had non-matching parentheses in the initrand function.
I fixed the declarations of your functions, use void when there are no parameters, initrand doesn't return anything.
Your division by RAND_MAX+1 was a little messed up. Simply divide by RAND_MAX and the result will be in the closed interval [0,1]. And the syntax for the conversion to float was not quite right.
If you want to get random double numbers in a specified range you can use this function
// Return a random double from a to b
double randomDouble(double a, double b)
{
return = ( rand() / ( (double)RAND_MAX + 1.0))
* (b - a) + a;
}

Resources