Picking random number between two points in C - c

I was wondering, is it possible to generate a random number between two limits in c. I.e. my program is set like this:
function x
{
generate random number;
}
while(1)
{
function x;
delay
}
so bascially I want a random number to be generated everytime the function is called , but the number has to be between, for example, 100 and 800
I know there is a already made function called random and randmize in stdlib.h
I just dont know how to create the upper and lower limits
Thank you

First, don't forget to seed your PRNG once and only once:
srand(time(NULL));
Then, this function should do what you want.
(lightly tested, seems to work)
int RandRange(int Min, int Max)
{
int diff = Max-Min;
return (int) (((double)(diff+1)/RAND_MAX) * rand() + Min);
}
In your case, you'll want to:
x = RandRange(100, 800); /* x will be between 100 and 800, inclusive */
This uses floating-point math, which may be slower than modulo (%) arithmetic, but will have less bias.

First get a random number between 0 and 1 (R). Then scale this to the desired range (R* (right limit - left limit)). Then add the min desired value.
int rand_between(int l, int r) {
return (int)( (rand() / (RAND_MAX * 1.0f)) * (r - l) + l);
}

Look at the modulus operator.
int r = rand();
r = (r % 700) + 100;
700 is the difference of the range.

Related

Why is my C code only generating every third random number?

I am trying to simulate the propagation of a worm across a network made of 100,000 computers. The simulation itself is very simple and I don't need any help except that for some reason, I am only getting every third random number.
Only the computers whose index modulo 1000 is less than 10 can be infected so when 1000 computers are infected, the program should be done. For some reason, my program only gets 329. When I lower the goal number and check the contents of the array, only every third computer has been changed and it is a consistent pattern. For example at the end of the array, only computers 98001, 98004, 98007, 99002, 99005, 99008 are changed even though the computers in between (98002, 98003, etc.) should be changed as well. The pattern holds all the way to the beginning of the array. When I try to get all 1000 changed, the program goes into an infinite loop and is stuck at 329.
Edit: I just discovered that if I lower the NETSIZE to 10,000 and the goal in the while loop to 100, it doesn't skip anything. Does that mean the problem has something to do with a rounding error? Someone who knows more about C than me must know the answer.
Thanks.
#include <stdio.h>
#include <stdlib.h>
#define NETSIZE 100000
double rand01();
void initNetwork();
unsigned char network[NETSIZE];
int scanrate = 3;
int infectedCount;
int scans;
int ind;
int time;
int main(void) {
initNetwork();
time = 0;
infectedCount = 1;
while (infectedCount < 1000) { //changing 1000 to 329 stops the infinite loop
scans = infectedCount * scanrate;
for (int j = 0; j < scans; j++) {
ind = (int) (rand01() * NETSIZE);
if (network[ind] == 0) {
network[ind] = 1;
infectedCount++;
}
}
time++;
}
for (int k = 0; k < NETSIZE; k++) {
if (network[k] == 1) printf("%d at %d\n", network[k], k);
}
}
double rand01() {
double temp;
temp = (rand() + 0.1) / (RAND_MAX + 1.0);
return temp;
}
void initNetwork() {
for (int i = 0; i < NETSIZE; i++) {
if (i % 1000 < 10) {
network[i] = 0;
} else {
network[i] = 2;
}
}
network[1000] = 1;
}
In the above code, I expect the code to run until the 1000 vulnerable indexes are changed from 0 to 1.
Converting comments into an answer.
What is RAND_MAX on your system? If it is a 15-bit or 16-bit value, you probably aren't getting good enough quantization when converted to double. If it is a 31-bit or bigger number, that (probably) won't be the issue. You need to investigate what values are generated by just the rand01() function with different seeds, plus the multiplication and cast to integer — simply print the results and sort -n | uniq -c to see how uniform the results are.
On my system RAND_MAX is only 32767. Do you think that might be why my results might not be granular enough? Now that you've made me think about it, there would only be 32,767 possible values and my network array is 100,000 possible values. Which corresponds about about the 1/3 results I am getting.
Yes, I think that is very probably the problem. You want 100,000 different values, but your random number generator can only generate about 33,000 different values, which is awfully close to your 1:3 metric. It also explains immediately why you got good results when you reduced the multiplier from 100,000 to 10,000.
You could try:
double rand01(void)
{
assert(RAND_MAX == 32767);
return ((rand() << 15) + rand()) / ((RAND_MAX + 1.0) * (RAND_MAX + 1.0));
}
Or you could use an alternative random number generator — for example, POSIX defines both the drand48() family of functions and
random(), with corresponding seed-setting functions where needed.
Yeah, the problem I am having is that the RAND_MAX value on my system is only 32767 and I am trying to effectively spread that out over 100,000 values which results in about only every third number ever showing up.
In my defense, the person who suggested the rand01() function has a PhD in Computer Science, but I think he ran this code on our school's main computer which probably has a much bigger RAND_MAX value.
#JonathanLeffler deserves credit for this solution.

Taylor Series logic in C

I am working on the project where we are approximating e^x using a taylor series, with x being a user entered value. The test values that we have been given are x=.5, x=1.0, and x=1.5. The goal is to get the output is supposed to be a table with a row for each iteration of the loop that creates the series, with the first column containing the number of iterations, the second column the theoretical value (based on exp(x)), the third the total of the summation, and the forth difference between the theoretical value and the iterated value.
My code as it is currently is below. As it stands, my logic has some hole in it, as the code builds and runs, but the output is not correct. If I were to take a stab at my problem, i think that my summation is not starting in the right spot (1), and that the first two terms are wrong (1+x+(x^2/2!)+(x^3/3!)... etc).
What logic should I be using vs what I have? Thanks.
//cs 1325
// Dean Davis
// Dr. Paulk
// series convergence homework.
#include <stdio.h>
#include <float.h> // need it for FLT_EPSILON
#include <math.h>
unsigned long factorial(int); // function will calculate the factorial
int main()
{
int n = 0;
unsigned long fact; // this variable will hold the factorial value
float x; // this will be the value read in from the user
double theoval; // this will hold the theoretical value of e^x
double holder; // will hold the value of the nth term
double total = 0; // will accumulate the total summation
double diff; // will hold the sifferential between theoretical value and the summation
puts("Please enter a numerical value greater than zero: "); // request input
scanf_s("%f", &x); // read it in
theoval=exp(x); // calc the theoretical value
printf("# Iter e^x Sum Diff\n");
printf("------- ------- ------- -------\n"); // set up the output
while ((theoval - total) >= FLT_EPSILON) //the loop to continue to sum the summation
{
fact = factorial(n); // calls the factorial function
holder = (pow(x, n)) / fact; // calculates the term n
total = total + holder; // adds to the sum
diff = theoval - total; // calc the diff
printf(" %-9d%-12.6f%-14.6f%-10.8f\n", n, theoval, total, diff); // output it
if ((theoval - total) >= FLT_EPSILON) // if it is smaller, then we don't wan't to increment n
continue;
else
n++;
}
printf("The number of iterations required for convergence is: %d\n", n); // out put this line
}
unsigned long factorial(int n)
{
unsigned long int fact=n;
if (n == 0) // if n is zero, 0!=1
return 1;
else // so long as it is not, then we can calculate it like this
{
n--; // decrement it
for (n; n > 0; n--)
{
fact = fact*n; // multiply the next number by the product of all the preceding terms
}
return fact;
}
}
Your main problem is here:
if ((theoval - total) >= FLT_EPSILON) // if it is smaller, then we don't wan't to increment n
continue;
else
n++;
The logic is both backwards and unnecessary. It's backwards because you avoid incrementing n in exactly those cases where you want to increment it, and it's unnecessary because in the other cases you're about to exit the loop anyway because the while expression is false. Just increment n unconditionally.
This expression is also a little suspect:
(theoval - total) >= FLT_EPSILON
The macro FLT_EPSILON is related to the spacing between representable float values near 1.0. The spacing is different in different places, so it does not make sense to use it as an absolute error bound. Since the Taylor series has a well defined error bound in the form of the remainder term, I suggest instead computing the maximum possible value of the remainder term for the current n, and exiting if the ratio of that bounding error value value to the current sum is less than some reasonably small value, such as maybe 0.00001.
Besides the issue with if ((theoval - total) >= FLT_EPSILON), there's an issue with the way you're doing factorial. Those values get big quick. 13! = 6227020800 which is outside the range of a 32-bit int, so any more than 13 iterations and you get invalid results.
You don't really want to compute factorial so much as you want to compute the next term. Each term is x / n times the prior term, so you can compute each term without having to explicitly compute x^n or n!.
int n = 1; // Start at 1 with the first term included so we don't divide by 0
double holder = 1; // will hold the value of the nth term
double total = 1; // will accumulate the total summation
while ((theoval - total) >= FLT_EPSILON) //the loop to continue to sum the summation
{
holder = holder * x / n; // compute the next term from the last one
total = total + term; // adds to the sum
printf(" %-9d%-12.6f%-14.6f%-10.8f\n", n, theoval, total, diff); // output it
n++;
}

To generate a random bit pattern with certain constraints

I want to generate a random stream of 0's & 1's (10000 iteration) under the constraint that 1 should occur only one out of 400 iteration .Can anyone help me out with it's C code and the libraries and the functions to be used in C.
Here's a solution that picks one hit out of an interval of 400 in advance and reports it if its turn comes; otherwise it emits a 0. When the hit is reported, the hit for the next interval is determined with rand(). The functon keeps its state with static variables and uses the special value -1 to initialise itself:
int pick(int n)
{
return 400 * rand() / ((double) RAND_MAX + 1);
}
int next()
{
static int hit = -1;
static int count;
if (hit < 0) hit = pick(WIDTH);
if (count++ == hit) {
hit = ((hit / WIDTH) + 1) * WIDTH + pick(WIDTH);
return 1;
}
return 0;
}
You call it like this:
for (i = 0; i < 10000; i++) {
printf("%8d %d\n", i, next());
}
This is different from Bathsheba's solution, because it guarantees a distribution of 1:399 if your sample is a multiple of 400. This means it might not be what you're looking for.
Edit I've introduced a new function pick that picks a random number between 0 (includive) and n (exclusive), which hopefully provides a better distribution than the modulo function.
400.0 * rand() / (RAND_MAX + 1.0) < 1 ? 1 : 0 is one way.
Drop the ternary if you're feeling confident and the expression matches the lvalue type. Note the careful placement of 400.0 and 1.0.
(Important note: don't accept this solution if you need an accurate 1 in 400 probability. This solution will not work well if RAND_MAX is a "very poor multiple" of 400. Given that the standard mandates RAND_MAX to be no lower than 32767, at that low value the statistical properties of this technique would be poor.)

Basic C Program, Babylonian Algorithm

I'm new to the C language and am trying to do a lab tutorial that we were given at uni.
We've been asked to do the following:
Task 1.
The Babylonian algorithm to compute the square root of a number n is as follows:
1. Make a guess at the answer (you can pick n/2 as your initial guess).
Compute r = n / guess
Set guess = (guess +r) / 2
Go back to step 2 for as many iterations as necessary. The more that steps 2 and 3 are
repeated, the closer guess will become to the square root of n.
Write a program that inputs an integer for n, iterates through the Babylonian algorithm
five times, and outputs the answer as a double to two decimal places. Your answer will
be most accurate for small values of n.
Here is what I have written:
#include <stdio.h>
#include <math.h>
int n;
main(void){
printf("Enter a value for n: ");
scanf("%d",&n);
double guess = n / 2;
for (int i = 0; i < 5; i++) {
double r = n / guess;
double guess = (guess + r) / 2;
}
printf("%d",guess);
}
Where have I gone wrong? It spits out ridiculous results; for example if I input "4" as n, the answer should be around "2", but it gives different huge results each time.
Another solution would be:
guess = guess / 2.0;
This would "force" a floating-point operation.
And the variable guess is already in the scope. You can´t redeclare it (as you did inside the loop). You can only set it a new value.
And you also need to change the printf to :
printf("%f",guess);
Check this link for more info about the printf formatters:
http://www.cplusplus.com/reference/cstdio/printf/
A few things wrong here.
First, you have scoped a second instance of guess inside the loop. Take away the double declaration on that line. So it should become:
guess = (guess + r) / 2;
Second, because guess is a double you need to use %f instead of %d in the printf call.
printf( "%f", guess );
Once you get it working, consider running the algorithm until a certain accuracy is achieved.
const double epsilon = 0.0001;
double guess = (double)n / 2.0;
double r = 0.0;
while( fabs(guess * guess - (double)n) > epsilon )
{
r = (double)n / guess;
guess = (guess + r) / 2.0;
}
The Babylonian Algorithm seems incorrect to me, it should be like this,
int i;
float n,guess=1;
printf("\nEnter the Number: ");
scanf("%f",&n);
for(i=0;i<PRECISION;i++)
{
guess=(guess+n/guess)/2;
}
printf("\nThe Square root of %f is %f",n,guess);
There are other possible errors also in your program,
There might be the problem of integer division,
The line double guess = n / 2;
should be double guess = (double) n / 2;
Also the printf() should be printf("%lf",guess);

Generate a random number within range? [duplicate]

This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
Generating Random Numbers in Objective-C
How do I generate a random number which is within a range?
This is actually a bit harder to get really correct than most people realize:
int rand_lim(int limit) {
/* return a random number between 0 and limit inclusive.
*/
int divisor = RAND_MAX/(limit+1);
int retval;
do {
retval = rand() / divisor;
} while (retval > limit);
return retval;
}
Attempts that just use % (or, equivalently, /) to get the numbers in a range almost inevitably introduce skew (i.e., some numbers will be generated more often than others).
As to why using % produces skewed results: unless the range you want is a divisor of RAND_MAX, skew is inevitable. If you start with small numbers, it's pretty easy to see why. Consider taking 10 pieces of candy (that we'll assume you can't cut, break, etc. into smaller pieces) and trying to divide it evenly between three children. Clearly it can't be done--if you hand out all the candy, the closest you can get is for two kids to get three pieces of candy, and one of them getting four.
There's only one way for all the kids to get the same number of pieces of candy: make sure you don't hand out the last piece of candy at all.
To relate this to the code above, let's start by numbering the candies from 1 to 10 and the kids from 1 to 3. The initial division says since there are three kids, our divisor is three. We then pull a random candy from the bucket, look at its number and divide by three and hand it to that kid -- but if the result is greater than 3 (i.e. we've picked out candy number 10) we just don't hand it out at all -- we discard it and pick out another candy.
Of course, if you're using a modern implementation of C++ (i.e., one that supports C++11 or newer), you should usually use one the distribution classes from the standard library. The code above corresponds most closely with std::uniform_int_distribution, but the standard library also includes uniform_real_distribution as well as classes for a number of non-uniform distributions (Bernoulli, Poisson, normal, maybe a couple others I don't remember at the moment).
int rand_range(int min_n, int max_n)
{
return rand() % (max_n - min_n + 1) + min_n;
}
For fractions:
double rand_range(double min_n, double max_n)
{
return (double)rand()/RAND_MAX * (max_n - min_n) + min_n;
}
For an integer value in the range [min,max):
double scale = (double) (max - min) / RAND_MAX;
int val = min + floor(rand() * scale)
I wrote this specifically in Obj-C for an iPhone project:
- (int) intInRangeMinimum:(int)min andMaximum:(int)max {
if (min > max) { return -1; }
int adjustedMax = (max + 1) - min; // arc4random returns within the set {min, (max - 1)}
int random = arc4random() % adjustedMax;
int result = random + min;
return result;
}
To use:
int newNumber = [aClass intInRangeMinimum:1 andMaximum:100];
Add salt to taste
+(NSInteger)randomNumberWithMin:(NSInteger)min WithMax:(NSInteger)max {
if (min>max) {
int tempMax=max;
max=min;
min=tempMax;
}
int randomy=arc4random() % (max-min+1);
randomy=randomy+min;
return randomy;
}
I use this method in a random number related class I made. Works well for my non-demanding needs, but may well be biased in some way.

Resources