Random number generator C - c

I can't seem to figure out why this is not working. I am trying to get these two void functions to generate randoms numbers when called in the main. I think the problem has to do with srand(time(NULL)); in the void function's. I think that when it gets called in the main and runs in the for loop, srand(time(NULL)); is not updated so it prints out the same number x times. numGen_10 should generate 1-10 and numGen_4 should generate 1-4 based on a variable.
What can I do to get the functions to output different random numbers each time the function is called?
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void numGen_10(int xOry, int* xRey);
void numGen_4(int num, int choice, int *choiceRe);
int main()
{
int x;
int num = 5;
for (int i = 0; i < 3; i++)
{
numGen_10(x, &x);
printf("val : %d \n", x);
}
printf("------------------------\n");
for (int i = 0; i < 4; i++)
{
numGen_4(4, x, &x);
printf("val2 : %d \n", x);
}
return 0;
}
void numGen_10(int xOry, int *xRey)
{
srand(time(NULL));
int r = rand() % 10 + 1;
xOry = r;
*xRey = xOry;
return;
}
void numGen_4(int num, int choice, int *choiceRe)
{
srand(time(NULL));
choice = rand() % num + 1;
*choiceRe = choice;
return;
}

The random number generator is completely deterministic; it will always output the same sequence of numbers for any given seed. srand() seeds the random number generator. So by calling srand() with the time immediately before each call to rand(), and since your loops will take less than a second to execute, you'll always get the same random number (or maybe two if the time happens to change in the middle).
Try calling srand() once before entering the loops.

Just for fun , add a delay of 1 second before each srand call when calling srand multiple times :
sleep(1);
/* or delay(1001); or usleep(500000);usleep(500000); based on availability */
srand(time(NULL));

Additional to what others said about solving problem of srand I would like to add a remark about how you use pointers, calling your functions with x and &x is pointless, you can just call either with pointer only or with variable only:
calling with pointer :
void numGen_10(int* xRey); // prototype
void numGen_10(int *xRey) // function's body
{
int r = rand() % 10 + 1;
*xRey = r;
return;
}
numGen_4(4, &x); // use from the main function
calling with variable :
int numGen_10(int xRey); // prototype
int numGen_10(int xRey) //function's body
{
int r = rand() % 10 + 1;
return r;
}
int y = numGen_4(4, x); // use from the main function

Related

How can I use two random numbers generated in a function as matrix coordinates?

I came up with this function to generate two random numbers, r and c, so that I can use them in as coordinates in matrix board[r][c]. Is this even possible?
int coordAleatoria()
{
srand((unsigned int)time(0));
int r=rand()%9;
int c=rand()%9;
while(r==c)
{
c=rand()%9;
}
printf("%d %d", r, c);
return r;
return c;
}
This is for a chess-like game. The PC is supposed to generate random moves. This function does generate coordinates, I'm just not sure how to make my program treat them as coordinates.
I hope I can get r and c in board[r][c] to be the values generated in coordAleatoria().
You cannot return more than one time. So you can combine the coordinates using structure as Jabberwocky suggested in the comment. If you are still finding it difficult than here is the implementation.
#include<stdio.h>
#include<stdlib.h>//for rand()
#include<time.h>//for time()
struct Pair
{
int row,col;
};
struct Pair coordAleatoria()
{
int r=rand()%9;
int c=rand()%9;
while(r==c)
{
c=rand()%9;
}
printf("Inside function: row=%d and col=%d\n",r,c);
//Create a pair
struct Pair p;
//Assign values
p.row=r,p.col=c;
//return it
return p;
}
int main()
{
srand((unsigned int)time(0));
//Get the returned value as a Pair
struct Pair p=coordAleatoria();
//Collect the row and column values
int r=p.row;
int c=p.col;
//Now you can use them here
printf("Outside function: row=%d and col=%d\n",r,c);
}
rand()%9 generates 9 different values. With while(r==c), looks like code is looking for 9*(9-1) or 72 different pairs. For a speedier approach, call rand() once.
Code could return a single int and later divine/mod by 9 to recover the row/column.
srand((unsigned int)time(0)); should not be repeated called in coordAleatoria(). Call it once, perhaps in main().
int coordAleatoria(void) {
int rc = rand()%72;
int r = rc/9;
int c = rc%9;
if (r==c) r++;
return (r*9) + c;
}
Rather than calling rand() twice (after properly seeding the random number generator with a call to srand()), you can simply call rand() once and take the first two digits as your coordinates, e.g.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
typedef struct {
int x, y;
} pair_t;
void rand_coords (pair_t *coords)
{
int n = rand();
coords->x = n % 10;
n /= 10;
coords->y = n % 10;
}
int main (void) {
pair_t coords = { .x = 0 };
srand (time (NULL)); /* seed random number generator */
rand_coords (&coords);
printf ("coords.x : %d\ncoords.y : %d\n", coords.x, coords.y);
return 0;
}
(or take the modulo of whatever your actual coordinate range is)
Example Use/Output
$ ./bin/coords_rand
coords.x : 9
coords.y : 8
$ ./bin/coords_rand
coords.x : 1
coords.y : 1
$ ./bin/coords_rand
coords.x : 5
coords.y : 7
$ ./bin/coords_rand
coords.x : 8
coords.y : 0

Changing the value of a variable with pointers not working

Basically I have a function called MinSubTab that is supposed to calculate the sum of the array passed and also to change the value passed in the first argument from inside the function without using return. This is done with pointers. Anyway, I think it'd be easier if I just showed you the code so here it is:
maintab.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "tab.h"
int main(){
int *reftab;
int min;
reftab = (int *)malloc(sizeof(int) * NMAX);
InitTab(reftab,NMAX);
printf("\n Total: %d et min: %d", MinSumTab(&min, reftab, NMAX), min);
free(reftab);
return 0;
}
tab.c
void InitTab(int *tab, int size){
srand(time(NULL));
for (int i=0; i<size; i++){
*(tab+i) = rand() % 10;
}
}
int MinSumTab(int *min, int *tab, int size){
int total=0;
int minimum = NMAX;
int temp = *min;
for (int i=0; i<size; i++){
total += *(tab+i);
}
for (int i=0; i<size; i++){
if(*(tab+i)<minimum){
minimum = *(tab+i);
}
}
*min = minimum;
return total;
}
So the expected result here is that the sum is printed (which it is) and the minimum value of the array is printed (which it is not). Every single time the min variable equals 8 and I've no idea how to actually change the value of min from within that function.
Please help as my brain has no more capacity for rational thought, it's been 1.5 hrs and no solution in sight. Thanks
Looks like a small mistake:
You initialize minimum with NMAX, which I assume is 8 (the size of the array). 99.9% of the random numbers will be bigger. So 8 is chosen as the minimum.
What you really want is to initialize it with RAND_MAX – the maximum value rand() can return.
In C order of evaluation and argument passing is undefined.
You can of course the order yourself but it only to feed your curiosity.
#include <stdio.h>
volatile char *message[] = {
"fisrt", "second", "third", "fourth"
};
int print(size_t x)
{
printf("%s\n", message[x]);
return x;
}
int main()
{
printf("%d %d %d %d\n", print(0), print(1), print(2), print(3));
return 0;
}
Note. There is one exception from this rule.
Logical operators are evaluated form the left to the right.
if( x != NULL && *x == 5)is safe because x will not be dereferenced if it is NULL

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.

How do you retrieve a number from a function to use it in another function?

(C code) Each die has its own function, and I want a function that will sum the outcome of each die. But how do I retrieve the values from the first and second functions and put them into the third to sum them? See below
int roll_die1(void)
{
int random_int;
srand((unsigned int)time(NULL));
random_int = rand() % (6) + 1;
printf("The outcome of your first Roll is: %d.\n", random_int);
return random_int;
}
int roll_die2(void)
{
int random_int2;
srand((unsigned int)time(NULL));
random_int2 = rand() % (6) + 1;
printf("The outcome of your second Roll is: %d.\n", random_int2);
return random_int2;
}
int calculate_sum_dice(int die1_value, int die2_value)
{
int sum = die1_value + die2_value;
return sum;
}
Now I can't just call the first two functions into the 3rd function, because it would repeat all the steps in those functions, so how do I do it?
Edit: In my main.c, to get the sum I did
roll1 = roll_die1();
roll2 = roll_die2();
sum = calculate_sum_dice(roll1, roll2);
Just allow calculate_sum_dice() to retrieve both results from roll_die1() and roll_die2() and return the sum. Their is no need to include any function parameters for calculate_sum_dice(). You can also just call srand() once in main(), as it just sets a seed for rand(), so it would be pointless to call it more than once. Have a look at srand(): why call it just once?, as pointed out by #Jonathan Leffler in the comments.
Here is what your code should look like:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int roll_die1(void) {
int random_int;
random_int = rand() % (6) + 1;
printf("The outcome of your first Roll is: %d.\n", random_int);
return random_int;
}
int roll_die2(void) {
int random_int2;
random_int2 = rand() % (6) + 1;
printf("The outcome of your second Roll is: %d.\n", random_int2);
return random_int2;
}
int calculate_sum_dice(void) {
int sum = roll_die1() + roll_die2();
return sum;
}
int main(void) {
srand((unsigned int)time(NULL));
int sum = calculate_sum_dice();
printf("Dice sum = %d\n", sum);
return 0;
}

My rand() function didn't work

this is my function: i need that every number that get random will be: one bigger than 50, one even, and one not even. i complied just with gcc and i'm using c99. It compiled well, but it when it print three random numbers it's print 0,0,and real random number. I want it to print for me three real numbers. thanks for who trying to help!
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define HIGH_NUMBER 100
int isValidNumbers(int num1,int num2, int num3);
int main(void)
{
srand (time(NULL));
int num1 = 0;
int num2 = 0;
int num3 = 0;
num1,num2,num3 =isValidNumbers(num1,num2,num3);
printf("%d %d %d\n",num1,num2,num3);
system("PAUSE");
return 0;
}
int isValidNumbers(int num1,int num2, int num3)
{
int i=1,ans = 0;
do
{
srand (time(NULL));
num1 = rand()%HIGH_NUMBER;
num2 = rand()%HIGH_NUMBER;
num3 = rand()%HIGH_NUMBER;
if ((num1%2==0||num2%2||num3%2==0)&&(num1%2==1||num2%2==1||num3%2==1)&&(num1>50||num2>50||num3>50))
{
return num1,num2,num3;
i--;
printf("%d %d %d",num1,num2,num3);
}
}
while (i);
}
Your function does not set the calling variables as you hoped for. You can't return more than one function value - and it makes no difference that you gave the same names to the variables in main and in the function - they are different variables, and as you wrote it, main just passes copies of those variable values.
Instead I pass pointers to those variables in this example. I also removed the return value of the function, since it now always returns valid values as your spec.
I removed srand within the function. It should be called once only, especially as I call the function 3 times in this example to show different results. If left in the function, all 3 calls would probably give the same result (unless a one-second timer boundary is bridged).
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define HIGH_NUMBER 100
void ValidNumbers(int *num1, int *num2, int *num3); // pointer arguments
int main(void)
{
int num1 = 0;
int num2 = 0;
int num3 = 0;
int tries;
srand ((unsigned)time(NULL)); // call once
for(tries=0; tries<3; tries++) {
ValidNumbers(&num1, &num2, &num3);
printf("%-2d %-2d %-2d\n", num1, num2, num3);
}
return 0;
}
void ValidNumbers(int *num1, int *num2, int *num3)
{
do {
*num1 = rand() % HIGH_NUMBER; // write through pointer of passed var
} while (*num1 <= 50); // number > 50
do {
*num2 = rand() % HIGH_NUMBER;
} while (*num2 % 2 != 0); // even number
do {
*num3 = rand() % HIGH_NUMBER;
} while (*num3 % 2 == 0); // odd number
}
Program output:
79 16 79
95 2 37
73 28 93
Returning multiple values is not allowed in C. So
return num1,num2,num3;
this will not work.
You can use a struct with 3 numbers and return that instead. You can go through this for an example of how do go about it.
Also note that the statement inside if after the return statement will never get executed, and are thus useless..
return num1,num2,num3;
i--; // <-- this will never get executed
printf("%d %d %d",num1,num2,num3); // <-- this will never get executed
There are two ways in C to return multiple parameters
One is mentioned above using 1 struct to hold all the return values inside struct.
Another is using pointer/address to hold the values.
I revised the script to show both ways. I will add a positive comment for HelloWorld, you guys are too harsh, it is an important concepts in c:
#include <stdlib.h>
#include <stdio.h>
#define HIGH_NUMBER 100
typedef struct Random Random;
Random *isValidNumbers(int *num1,int *num2, int *num3);
struct Random{
int a;
int b;
int c;
};
int main(void)
{
int num1 = 0;
int num2 = 0;
int num3 = 0;
/* pr to use as parameter, rr used as a return struct , just for demoo purpuse*/
Random *p;
p = isValidNumbers(&num1,&num2,&num3);
printf("%d %d %d main return random numbers\n",num1,num2,num3);
printf("%d %d %d main return from struct \n",p->a,p->b,p->c);
return 0;
}
Random *isValidNumbers(int *num1,int *num2, int *num3)
{
struct Random *r = malloc(sizeof(Random));
int i=1,ans = 0;
do
{
srand (time(NULL));
*num1 = rand()%HIGH_NUMBER;
*num2 = rand()%HIGH_NUMBER;
*num3 = rand()%HIGH_NUMBER;
r->a = *num1;
r->b = *num2;
r->c = *num3;
if ((*num1%2==0||*num2%2||*num3%2==0)&&(*num1%2==1||*num2%2==1||*num3%2==1)&&(*num1>50||*num2>50||*num3>50))
{
i--;
printf("%d %d %d inside isValidNumber\n",*num1,*num2,*num3);
break;
}
}
while (i);
return r;
}
Results:
cmake28 ..
make
[gliang#www build]$ ./src/random
99 99 44 inside isValidNumber
99 99 44 main return random numbers
99 99 44 main return from struct

Resources