c random number on time - c

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

Related

Can't get random numbers in c

I am trying to get two random numbers between 0 and 11 but i get the same number whenever i execute my code. These numbers are 7 and 10. Here is my code:
void track_machine(){
int X = 0,Y = 0; //Coordinates
double D = 0,R = 0; //Distance and replacement
refresh_position(&X,&Y,&D,&R);
printf("%d\n",X);
printf("%d\n",Y);
}
void refresh_position(int *X, int *Y, double *D, double *R){
*X = rand()%12;
*Y = rand()%12;
}
With
#include <stdlib.h> /* srand, rand */
#include <time.h> /* time */
call srand(time(NULL)); at the start of your program - before you use rand() - to set a different seed every time.
The "random-number-generator" is, despite its name, still a deterministic algorithm. When starting with the same seed values (when srand is not called), it will always produce the same results.

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.

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

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

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
...

Precedence rules - Trouble using brackets and division with srand to get a float number

I am trying to manipulate srand so that srand returns a decimal number by division. But it's not working. My Code doesn't return a decimal number even though precedence rules should prioritize brackets before division.
#include <stdio.h>
#include <math.h>
int main(void) {
double save;
srand(time(NULL));
save = (rand() % 100)/ 10;
printf("%f", save);
return 0;
}
However this code works fine, but I'm not happy with the solution.
#include <stdio.h>
#include <math.h>
int main(void) {
double save;
srand(time(NULL));
save = rand() % 100;
save = save / 10;
printf("%f", save);
return 0;
}
Can anyone explain this and give a better solution?
Problem of this code:
double save;
save = (rand() % 100) / 10;
is not in precedence of operators, but because of division by integral constant 10. Try:
save = (rand() % 100) / 10.0;
yet in case you want to generate numbers from interval <0; 10) it would better to do:
save = ((double)rand() / ((double)RAND_MAX + 1.0)) * 10.0;
which will yield more precise results that will also be more uniformly distributed :)
It has no relation with Operator precedence!
rand() returns int type and dividing it by an integer will also return int value. You have to cast (rand() % 100)/ 10 to double
save = (double) (rand() % 100)/ 10;
In second case
save = rand() % 100;
promotes value obtained by rand() % 100 to double. And then dividing save by 10 is giving you right answer, i,e, double.

Resources