I am more than likely doing this whole code wrong, but when attempting the find the range of:
4.0*rand()/RAND_MAX + 1
I end up only getting the number 0 as a result, and I'm pretty sure there's more to it than that.
Code (in C):
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main()
{
srand(time(NULL));
int r;
4.0*rand()/RAND_MAX+1;
printf("%i",r);
return 0;
}
double rr = 4.0*rand()/RAND_MAX+1; You need to use a double and more importantly assign the result (rr) to some variable.
printf("%lf",rr); For printing the result.
As far as it is seen there is no range calculation here.
You are simply printing an uninitialized variable(r). (which seems to comtain the value 0 when you printed).
Two things:
First, you are never assigning r any value. You need to change 4.0*rand()/RAND_MAX+1; to r = 4.0*rand()/RAND_MAX+1;
Second, the compiler will likely complain about that since you're degrading from double to int. You should change 4.0 to 4.
The final code should look roughly like r = 4*rand()/RAND_MAX+1;. Then, the range will be {1, 2, 3, 4, 5} (note: depends on whether rand can return RAND_MAX or only less than RAND_MAX. If only less, then exclude 5.) If you wanted {0, 1, 2, 3} you needed to enclose RAND_MAX+1 in parentheses.
Note: as pointed out in the comments, there may be some concerns with the above. You can use something like this to get exactly the same distribution:
r = rand()
if (r == RAND_MAX) return 5;
else return r % 4 + 1;
If you don't ever want to return 5, you can use rejection sampling:
r = RAND_MAX;
while (r == RAND_MAX) r = rand();
return r % 4 + 1;
Related
There is this Mario problem in the CS50 course and it's easy using the recursion method, except that when I try to add any arithmetic operation it shows (invalid operands to binary expression ('void' and 'int')). It's just for the sake of me to understand what I can do using recursion and what I can't; the problem is this line (sum(n-1)+n;)
Here is the code:
#include <cs50.h>
#include <stdio.h>
void sum(int n);
int main ()
{
int u = get_int("f");
sum (u);
}
void sum(int n)
{
if (n==0)
{
return;
}
sum(n-1)+n;
for(int i = 0 ; i < n; i++)
{
printf( "#");
}
printf("\n");
}
The error you are seeing is from this line:
sum(n-1)+n;
sum is a function that returns void, but you are trying to add it with an integer n.
I am not quite sure what that get_int("f") does, but I assume it's prompting to the user for an int input, and you are trying to sum from 0 to that number. Here is the solution:
int sum(int n) // Here is the critical change to your code, now it returns an int
{
if (n == 1) // Root case that will stop the recursion, otherwise, it's endless
return 1; // 1 = 1 + 0;
return sum(n-1) + n; // Recursion
}
Think about what we are trying to achieve here. We want to add from 0 to n, or to say from n to 0 downwards. If n is 3, it's going to be 3+2+1+0, and you'll notice that 3 is just n, and 2 is n - 1, 1 is (n - 1) - 1, etc. To visualize it:
before sum(3) could return anything, it calls sum(2) + 3;
before sum(2) could return anything, it calls sum(1) + 2;
1 is our root case, and there is no more calls, so sum(1) is going to return 1;
that 1 is returned to step 2, so sum(1) + 2 becomes 1 + 2, which is 3, and that is the value sum(2), and it returns its result to step 1, and step 1 becomes 3 + 3, which is 6, and the initial call to sum is then completed.
I hope that makes sense to you. Recursion is not an easy technique to master. Take your time, but you need to understand how function calls work in memory. Here is a video that illustrates how recursive calls in memory look like, Data Structures Using C++: Illustration of Recursive Function Calls (Call Stack).
It is because the return type of the function sum() is void.
You cannot add anything to void.
Anyway the result of the "addition" is thrown away, so you won't need addition.
This mean that sum ( n-1)+n; should be replaced with sum ( n-1);.
So I just got my grade back from a school project that I did well on, but the grader took five points off because I didn't make a call to ceil(...). Its a parallel computing course using CUDA, but the question isn't directly related to any CUDA feature.
Here is the "offending" line:
dim3 dimGrid(n / dimBlock.x, n / dimBlock.y);
His claim is that I should have done:
dim3 dimGrid(ceil(n / dimBlock.x), ceil(n / dimBlock.y));
So my question is, why would I be marked off for this if n and dimBlock.* are integers? Their result will be calculated before ceil is even called and truncated. Thus it seems silly to mark off for that.
The following examples below seem to show that GCC optimizes the call out anyway when using -O2.
With ceil:
#include <stdio.h>
#include <math.h>
int main()
{
int m = 3, n = 5, o;
o = ceil(n / m);
printf("%d\n", o);
return 0;
}
Without:
#include <stdio.h>
#include <math.h>
int main()
{
int m = 3, n = 5, o;
o = n / m;
printf("%d\n", o);
return 0;
}
While I understand its only five points, I still want to understand why if I am completely wrong.
The grader probably meant that you needed to use the ceiling of the fraction n/d, and this is perfectly right: this way there will be enough blocks to cover n, the last block possibly being incomplete.
That does not mean that the appropriate implementation is with the C expression ceil(n/d). Indeed, the C / is an integer division and will discard the decimal part, actually taking the floor of the fraction.
You can use ceil((double)n/(double)d) instead.
But my favorite way would be without converting to doubles: (n+d-1)/d.
here, m = 3, n = 5
so, n / m= 1.67(approx);
since you are assigning it o which is of int type, it will truncate it. i.e, only stores the integer part not decimal part, so we have o=1. While if you will use ceil(n/m), output would be 2, which is then assigned to o. i.e, o=2.
I have to create a function that does successive substitution.
For example,
I have a function F(X,Y) = (sqrt ((X-Y)/(X-1))) / tanh(sqrt((X-Y)/(X-1))) .
(X is a constant)
I have to enter and check values of Y (smaller than X) like this:
Value 1: SET Y=0
E1 = F(X,Y)
then E2 = F(X,E1)
THEN E3 = F(X,E2)
.
.
.
.
E(n) = F(X,E(n-1))
and stop when (fabs(E(n)-E(n-1))<= 0.001);
I tried to use a do-while loop but I didn't manage to make it work.
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#define F(Ei,E) (sqrt (M*(Ei-E)/(Ei-1))) / tanh(sqrt(M*(Ei-E)/(Ei-1)))
#define Ei 1 + ((Db*CBoo)/(b*Da*CAi))
#define M (Da*k2*CBoo)/(kl*kl)
int main(){
double k2,Da,Db,b,h,CAi,CBoo,kl,E,i;
double E1 ,E2 ;
kl =1;
k2 = 3;
Da = 0.4;
Db = 0.3;
CAi = 3;
CBoo = 5;
b = 2;
E1=0;
E2=0;
E=0;
i=0;
do
{
E1 = E2;
E2 = F(Ei,E1);
printf("dd");
}while(fabs(E2-E1)<= 0.0001);
printf("\nanswer is %lf",E1);
system("PAUSE");
}
The loop only does 1 round and the answer is always 0
Any ideas how to do this??
Thank you!
You should use while(fabs(E2-E1) > 0.001) instead of while(fabs(E2-E1) <= 0.001)
First, you need to change while(fabs(E2-E1) <= 0.001) to while(fabs(E2-E1) > 0.001) as was pointed out by MicroAlex.
The reason it still doesn't work is that the term sqrt(X-Y) restricts the domain of your function F(X,Y) to the interval [0, X] unless you are prepared to deal with complex numbers (which you are not, obviously). With your starting point Y0=0, you immediately get a new Y1=F(X,Y0) outside the domain of your function. This is why it breaks after one iteration. As a matter of fact you're lucky it breaks since the behaviour of the loop condition is essentially undefined.
So the real problem lies in your numerical approach. The problem doesn't seem to yield to fixed-point iteration. What are you trying to do, actually?
edit
The reason why fixed-point iteration doesn't work is probably that the function is not Lipschitz-continuous (due to the sqrt term, but I haven't checked). You might be better off with trying a different root solver, like bisection with a start interval [0, X]
While searching for Tutorials on generating random numbers in C I found this topic
When I try to use the rand() function without parameters, I always get 0. When I try to use the rand() function with parameters, I always get the value 41. And whenever I try to use arc4random() and random() functions, I get a LNK2019 error.
Here's what I've done:
#include <stdlib.h>
int main()
{
int x;
x = rand(6);
printf("%d", x);
}
This code always generates 41. Where am I going wrong? I'm running Windows XP SP3 and using VS2010 Command Prompt as compiler.
You should call srand() before calling rand to initialize the random number generator.
Either call it with a specific seed, and you will always get the same pseudo-random sequence
#include <stdlib.h>
int main ()
{
srand ( 123 );
int random_number = rand();
return 0;
}
or call it with a changing sources, ie the time function
#include <stdlib.h>
#include <time.h>
int main ()
{
srand ( time(NULL) );
int random_number = rand();
return 0;
}
In response to Moon's Comment
rand() generates a random number with an equal probability between 0 and RAND_MAX (a macro pre-defined in stdlib.h)
You can then map this value to a smaller range, e.g.
int random_value = rand(); //between 0 and RAND_MAX
//you can mod the result
int N = 33;
int rand_capped = random_value % N; //between 0 and 32
int S = 50;
int rand_range = rand_capped + S; //between 50 and 82
//you can convert it to a float
float unit_random = random_value / (float) RAND_MAX; //between 0 and 1 (floating point)
This might be sufficient for most uses, but its worth pointing out that in the first case using the mod operator introduces a slight bias if N does not divide evenly into RAND_MAX+1.
Random number generators are interesting and complex, it is widely said that the rand() generator in the C standard library is not a great quality random number generator, read (http://en.wikipedia.org/wiki/Random_number_generation for a definition of quality).
http://en.wikipedia.org/wiki/Mersenne_twister (source http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html ) is a popular high quality random number generator.
Also, I am not aware of arc4rand() or random() so I cannot comment.
You need to seed your PRNG so it starts with a different value each time.
A simple but low quality seed is to use the current time:
srand(time(0));
This will get you started but is considered low quality (i.e. for example, don't use that if you are trying to generate RSA keys).
Background. Pseudo-random number generators do not create true random number sequences but just simulate them. Given a starting point number, a PRNG will always return the same sequence of numbers. By default, they start with the same internal state so will return the same sequence.
To not get the same sequence, you change the internal state. The act of changing the internal state is called "seeding".
#include <stdlib.h>
int main()
{
int x;
x = rand(6);
printf("%d", x);
}
Especially as a beginner, you should ask your compiler to print every warning about bad code that it can generate. Modern compilers know lots of different warnings which help you to program better. For example, when you compile this program with the GNU C Compiler:
$ gcc -W -Wall rand.c
rand.c: In function `main':
rand.c:5: error: too many arguments to function `rand'
rand.c:6: warning: implicit declaration of function `printf'
You get two warnings here. The first one says that the rand function only takes zero arguments, not one as you tried. To get a random number between 0 and n, you can use the expression rand() % n, which is not perfect but ok for small n. The resulting random numbers are normally not evenly distributed; smaller values are returned more often.
The second warning tells you that you are calling a function that the compiler doesn't know at that point. You have to tell the compiler by saying #include <stdio.h>. Which include files are needed for which functions is not always simple, but asking the Open Group specification for portable operating systems works in many cases: http://www.google.com/search?q=opengroup+rand.
These two warnings tell you much about the history of the C programming language. 40 years back, the definition of a function didn't include the number of parameters or the types of the parameters. It was also ok to call an unknown function, which in most cases worked. If you want to write code today, you should not rely on these old features but instead enable your compiler's warnings, understand the warnings and then fix them properly.
Also, linear congruential PRNGs tend to produce more randomness on the higher bits that on the lower bits, so to cap the result don't use modulo, but instead use something like:
j = 1 + (int) (10.0 * (rand() / (RAND_MAX + 1.0)));
(This one is from "Numerical Recipes in C", ch.7)
You first need to seed the generator because it doesn't generate real random numbers!
Try this:
#include <stdlib.h>
#include <time.h>
int main()
{
// random seed, time!
srand( time(NULL) ); // hackish but gets the job done.
int x;
x = rand(); // everytime it is different because the seed is different.
printf("%d", x);
}
Or, to get a pseudo-random int in the range 0 to 19,
for example, you could use the higher bits like this:
j = ((rand() >> 15) % 20;
int *generate_randomnumbers(int start, int end){
int *res = malloc(sizeof(int)*(end-start));
srand(time(NULL));
for (int i= 0; i < (end -start)+1; i++){
int r = rand()%end + start;
int dup = 0;
for (int j = 0; j < (end -start)+1; j++){
if (res[j] == r){
i--;
dup = 1;
break;
}
}
if (!dup)
res[i] = r;
}
return res;
}
While searching for Tutorials on generating random numbers in C I found this topic
When I try to use the rand() function without parameters, I always get 0. When I try to use the rand() function with parameters, I always get the value 41. And whenever I try to use arc4random() and random() functions, I get a LNK2019 error.
Here's what I've done:
#include <stdlib.h>
int main()
{
int x;
x = rand(6);
printf("%d", x);
}
This code always generates 41. Where am I going wrong? I'm running Windows XP SP3 and using VS2010 Command Prompt as compiler.
You should call srand() before calling rand to initialize the random number generator.
Either call it with a specific seed, and you will always get the same pseudo-random sequence
#include <stdlib.h>
int main ()
{
srand ( 123 );
int random_number = rand();
return 0;
}
or call it with a changing sources, ie the time function
#include <stdlib.h>
#include <time.h>
int main ()
{
srand ( time(NULL) );
int random_number = rand();
return 0;
}
In response to Moon's Comment
rand() generates a random number with an equal probability between 0 and RAND_MAX (a macro pre-defined in stdlib.h)
You can then map this value to a smaller range, e.g.
int random_value = rand(); //between 0 and RAND_MAX
//you can mod the result
int N = 33;
int rand_capped = random_value % N; //between 0 and 32
int S = 50;
int rand_range = rand_capped + S; //between 50 and 82
//you can convert it to a float
float unit_random = random_value / (float) RAND_MAX; //between 0 and 1 (floating point)
This might be sufficient for most uses, but its worth pointing out that in the first case using the mod operator introduces a slight bias if N does not divide evenly into RAND_MAX+1.
Random number generators are interesting and complex, it is widely said that the rand() generator in the C standard library is not a great quality random number generator, read (http://en.wikipedia.org/wiki/Random_number_generation for a definition of quality).
http://en.wikipedia.org/wiki/Mersenne_twister (source http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html ) is a popular high quality random number generator.
Also, I am not aware of arc4rand() or random() so I cannot comment.
You need to seed your PRNG so it starts with a different value each time.
A simple but low quality seed is to use the current time:
srand(time(0));
This will get you started but is considered low quality (i.e. for example, don't use that if you are trying to generate RSA keys).
Background. Pseudo-random number generators do not create true random number sequences but just simulate them. Given a starting point number, a PRNG will always return the same sequence of numbers. By default, they start with the same internal state so will return the same sequence.
To not get the same sequence, you change the internal state. The act of changing the internal state is called "seeding".
#include <stdlib.h>
int main()
{
int x;
x = rand(6);
printf("%d", x);
}
Especially as a beginner, you should ask your compiler to print every warning about bad code that it can generate. Modern compilers know lots of different warnings which help you to program better. For example, when you compile this program with the GNU C Compiler:
$ gcc -W -Wall rand.c
rand.c: In function `main':
rand.c:5: error: too many arguments to function `rand'
rand.c:6: warning: implicit declaration of function `printf'
You get two warnings here. The first one says that the rand function only takes zero arguments, not one as you tried. To get a random number between 0 and n, you can use the expression rand() % n, which is not perfect but ok for small n. The resulting random numbers are normally not evenly distributed; smaller values are returned more often.
The second warning tells you that you are calling a function that the compiler doesn't know at that point. You have to tell the compiler by saying #include <stdio.h>. Which include files are needed for which functions is not always simple, but asking the Open Group specification for portable operating systems works in many cases: http://www.google.com/search?q=opengroup+rand.
These two warnings tell you much about the history of the C programming language. 40 years back, the definition of a function didn't include the number of parameters or the types of the parameters. It was also ok to call an unknown function, which in most cases worked. If you want to write code today, you should not rely on these old features but instead enable your compiler's warnings, understand the warnings and then fix them properly.
Also, linear congruential PRNGs tend to produce more randomness on the higher bits that on the lower bits, so to cap the result don't use modulo, but instead use something like:
j = 1 + (int) (10.0 * (rand() / (RAND_MAX + 1.0)));
(This one is from "Numerical Recipes in C", ch.7)
You first need to seed the generator because it doesn't generate real random numbers!
Try this:
#include <stdlib.h>
#include <time.h>
int main()
{
// random seed, time!
srand( time(NULL) ); // hackish but gets the job done.
int x;
x = rand(); // everytime it is different because the seed is different.
printf("%d", x);
}
Or, to get a pseudo-random int in the range 0 to 19,
for example, you could use the higher bits like this:
j = ((rand() >> 15) % 20;
int *generate_randomnumbers(int start, int end){
int *res = malloc(sizeof(int)*(end-start));
srand(time(NULL));
for (int i= 0; i < (end -start)+1; i++){
int r = rand()%end + start;
int dup = 0;
for (int j = 0; j < (end -start)+1; j++){
if (res[j] == r){
i--;
dup = 1;
break;
}
}
if (!dup)
res[i] = r;
}
return res;
}