Consider the following C program :
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
int main()
{
srand(time(NULL));
for (int i = 0; i < 20; ++i) {
static float a = 0;
a = (rand() % 2001 - 1000) / 2.e3;
printf("%.4f ", a);
}
}
This will successfully generate then print a list of random number between -0.5 to 0.5. For example :
./main.out
-0.2475 -0.3640 -0.3945 0.2995 0.0460 0.2230 -0.0340 0.1630 -0.2275 -0.3450 0.3560 -0.4335 -0.0025 -0.2980 -0.0505 -0.1815 0.3115 -0.4465 -0.1325 -0.2340
I checked the Precedence of Operators and still don't understand how the expression (rand()%2001 - 1000)/2.e3 works.
(especially where does the negative sign comes from)
Let's analyze the expression (rand() % 2001 - 1000) / 2.e3:
the rand() function defined in <stdlib.h> returns a pseudo random integer of type int in the range 0 to RAND_MAX inclusively. RAND_MAX is a constant also defined in <stdlib.h> whose value is at least 32767.
rand() % 2001 computes the remainder of the division by 2001. Since rand() is positive, the result is a pseudo random number in the range 0 to 2000 inclusive, with a small bias caused by 2001 not dividing RAND_MAX evenly.
rand() % 2001 - 1000 is evaluated as (rand() % 2001) - 1000, the range of the result is shifted by 1000 toward the negatives, namely between -1000 and 1000 inclusively.
to evaluate (rand() % 2001 - 1000) / 2.e3, the value obtained from the previous steps is converted to type double and divided by 2.e3, which would be more readable as 2000.0. Hence the result is a floating point value of type double with 2001 possible distinct values between -0.5 and 0.5 inclusively.
a = (rand() % 2001 - 1000) / 2.e3; converts this double value to float, the type of a. The float value will be implicitly converted back to type double when passed to printf, this conversion does not produce exactly the same number in many cases.
note that there is no reason to define a as a static variable.
Here is an alternative implementation that produces more distinct values in the same inclusive range with a slightly less biased distribution:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main() {
srand(time(NULL));
for (int i = 0; i < 20; ++i) {
double a = rand() / (double)RAND_MAX - 0.5;
printf("%f ", a);
}
printf("%\n");
return 0;
}
a = (rand() % 2001 - 1000) / 2.e3;
rand() is evaluated first
a = (rand() % 2001 - 1000) / 2.e3;
^^^^^^ int between `0` and `RAND_MAX` inclusive
Then the modulus operator generates a value between 0 and 2000.
a = ([0 .. 2000] - 1000) / 2.e3;
^^^^^^^^^^^ int
Then that value has 1000 subtracted, becoming a value between -1000 and 1000
a = ([-1000 .. 1000]) / 2.e3;
^^^^^^^^^^^^^^^ int
Then, divided by 2000.0 (or 2.e3) generates a double between -0.5 and 0.5
a = [-0.5 .. 0.5];
^^^^^^^^^^^^^ double
Related
I am writing a C program that will be able to accept an input value that dictates the number of iterations that will be used to estimate Pi.
For example, the number of points to be created as the number of iterations increases and the value of Pi also.
Here is the code I have so far:
#include <stdio.h>
#include <stdlib.h>
main()
{
const double pp = (double)RAND_MAX * RAND_MAX;
int innerPoint = 0, i, count;
printf("Enter the number of points:");
scanf("%d", &innerPoint);
for (i = 0; i < count; ++i){
float x = rand();
float y = rand();
if (x * x + y * y <= 1){
++innerPoint;
}
int ratio = 4 *(innerPoint/ i);
printf("Pi value is:", ratio);
}
}
Help fix my code as I'm facing program errors.
rand() returns an integer [0...RAND_MAX].
So something like:
float x = rand()*scale; // Scale is about 1.0/RAND_MAX
The quality of the Monte Carlo method is dependent on a good random number generator. rand() may not be that good, but let us assume it is a fair random number generator for this purpose.
The range of [0...RAND_MAX] is RAND_MAX+1 different values that should be distributed evenly from [0.0...1.0].
((float) rand())/RAND_MAX biases the end points 0.0 and 1.0 giving them twice the weight of others.
Consider instead [0.5, 1.5, 2.5, ... RAND_MAX + 0.5]/(RAND_MAX + 1).
RAND_MAX may exceed the precision of float so converting rand() or RAND_MAX, both int, to float can incurring rounding and further disturb the Monte Carlo method. Consider double.
#define RAND_MAX_P1 ((double)RAND_MAX + 1.0)
// float x = rand();
double x = ((double) rand() + 0.5)/RAND_MAX_P1;
x * x + y * y can also incur excessive rounding. C has hypot(x,y) for a better precision sqrt(x*x + y*y). Yet here, with small count, it likely makes no observable difference.
// if (x * x + y * y <= 1)
if (hypot(x, y <= 1.0))
I am sure it is not the best solution, but it should do the job and is similar to your code. Use a sample size of at least 10000 to get a value near PI.
As mentioned in the commenter: You should look at the data types of the return values functions give you.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main()
{
// Initialize random number generation
srand(time(NULL));
int samples = 10000;
int points_inside =0;
// Read integer - sample size (use at least 10000 to get near PI)
printf("Enter the number of points:");
scanf("%d", &samples);
for (int i = 0; i < samples; ++i){
// Get two numbers between 0 and 1
float x = (float) rand() / (float)RAND_MAX;
float y = (float) rand() / (float)RAND_MAX;
// Check if point is inside
if (x * x + y * y <= 1){
points_inside++;
}
// Calculate current ratio
float current_ratio = 4 * ((float) points_inside / (float) i);
printf("Current value of pi value is: %f \n", current_ratio);
}
}
I'm learning about the rand() function in C, as I want to use it to generate a random number in a range. However, I have a question about a part of the algorithm below.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main()
{
const MAX = 20, MIN = 1;
srand(time(NULL));
int randNumber = rand() % (MAX - MIN + 1) + MIN;
printf("%d", randNumber);
// yeu cau nhap so
int duDoan;
printf("Moi ban du doan con so:");
scanf("%d", &duDoan);
// chay vong lap kiem tra
while(duDoan != randNumber) {
printf("Ban da sai. Moi nhap lai:");
scanf("%d", &duDoan);
}
printf("Ban da nhap dung. Dap an la: %d ", randNumber);
return 0;
}
What confuses me here is why we have to add + MIN in this line:
rand() % (MAX - MIN + 1) + MIN;
If I leave it, what will the result be?
rand() is a number between 0 and RAND_MAX.
rand() % n is a number between 0 and n - 1. If you want a value from 0 to n, then you need rand() % (n+1).
In your example (MAX - MIN + 1) is the span of integer values to generate, while MIN is the lower value. So for example where:
MIN = -10
MAX = 10
the span n :
n = (MAX - MIN + 1) = 21
so that:
rand() % n
yields values from 0 to 20, and
rand() % n - MIN
is -10 to +10. Without the +1, it would incorrectly be -10 to +9.
Note that where a statistically high quality random number is required restricting the span by the use of % is flawed and will introduce a bias when n is not a factor of RAND_MAX + 1. In that case (int)(n * ((double)rand() / (double)RAND_MAX)) is a better solution, so you would have:
int randNumber = (int)((MAX - MIN) * ((double)rand() /
(double)RAND_MAX)) + MIN ;
Note there is no +1 here because the range of (double)rand() / (double)RAND_MAX is 0 to 1, so multiplying by n gives 0 to n inclusive.
I have to involve experimental data in my code by addressing a method for automated generation of non-trivial input test data.How can I do this,considering the fact that I also have to take into consideration numbers of double type?
Here's some additional context.From page 139 from this book http://mimoza.marmara.edu.tr/~msakalli/cse706_12/SkienaTheAlgorithmDesignManual.pdf which is more accurately page 151 from the PDF,I had to solve problem 4.3,which I did.However I need to generate random input for this problem,and since I have to deal with real numbers,it will most likely be needed to generate double numbers.Problem is I don't know what range I should choose for this case when generating real numbers.
To achieve a random double in the range of [-DBL_MAX ....DBL_MAX] with about equal chance of any double appearing, randomly populate a double. Reject non-finite ones.
#include <math.h>
#include <stdlib.h>
double rand_finite_double(void) {
union {
double d;
unsigned char uc[sizeof(double)];
} u;
do {
for (unsigned i = 0; i < sizeof u.uc; i++) {
u.uc[i] = (unsigned char) rand();
}
} while (!isfinite(u.d));
return u.d;
}
Somewhat linearly inefficient given only 8 bits typically generated each loop iteration.
C's rand() returns an int, typically 32 bits. A double has 53 bits of mantissa. So to create a good random double you'll have to generate 53 random bits. Try something like this:
double rd() {
uint64_t r53 = ((uint64_t)(rand()) << 21) ^ (rand() >> 2);
return (double)r53 / 9007199254740991.0; // 2^53 - 1
}
This will return a double in the interval [0, 1]
for examle 0 to max:
double pseudorand(double max)
{
srand((unsigned) time(0));
return (max / RAND_MAX) * rand();
}
or from -max to max
double pseudorand(double max)
{
srand((unsigned) time(0));
return (rand() > RAND_MAX / 2 ? -1 : 1) *(max / RAND_MAX) * rand();
}
https://onlinegdb.com/SyqGH9PqN
How can i generate random doubles in C?
No bells and whistles, but will get you started:
double drand ( double low, double high )
{
srand((unsigned int)clock());
return ( (double)rand() * ( high - low ) ) / (double)RAND_MAX + low;
}
For low = 10.0;
and high = 1000.0
a call to this function will generate a single value:
10 >= value <= 1000.0
Adapted from this example.
This question already has answers here:
How to generate random float number in C
(6 answers)
Random float number generation
(14 answers)
Generate random between [0, 1)
(2 answers)
Closed 5 years ago.
I have found a code in this answer How to generate a random integer number from within a range a code that works perfectly, but tis is for integers. Does anybody know how can I change this code so it returns uniformly a number between 0 and 1?
#include <stdlib.h> // For random(), RAND_MAX
// Assumes 0 <= max <= RAND_MAX
// Returns in the closed interval [0, max]
long random_at_most(long max) {
unsigned long
// max <= RAND_MAX < ULONG_MAX, so this is okay.
num_bins = (unsigned long) max + 1,
num_rand = (unsigned long) RAND_MAX + 1,
bin_size = num_rand / num_bins,
defect = num_rand % num_bins;
long x;
do {
x = random();
}
// This is carefully written not to overflow
while (num_rand - defect <= (unsigned long)x);
// Truncated division is intentional
return x/bin_size;
}
You really don't need all that complicated code there. Imagining you initialized your pseudo-random number generator correctly in your main function, with for instance something like this for rand:
srand(time(NULL));
The following code should be enough:
double random(){
return (double)rand()/RAND_MAX;
}
The idea there is just to pick a random number between 0 and RAND_MAX, and then to divide it by RAND_MAX. As RAND_MAX/RAND_MAX is equal to 1, you will return a random value between 0 and 1.
The C way:
#include <stdlib.h>
int main(int argc, char** argv)
{
printf("Random value: %f\n", (float) rand() / (float) RAND_MAX);
return 0;
}
The C++11 way:
#include <random>
int main(int argc, char** argv)
{
std::default_random_engine generator;
std::uniform_real_distribution<float> distribution(0.0, 1.0);
printf("Random value: %f\n", distribution(generator));
return 0;
}
How can I generate random numbers from 0 to 1000000?
I already tried the code below, but it still gives me numbers from 0 to 32767 (RAND_MAX):
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(){
int i,x;
srand(time(NULL));
for(i=0; i<10000; i++){
int x = rand() % 10000000 + 1;
printf("%d\n",x);
}
return 0;
}
[Edit] The initial answer was for 0 to 1,000,000. I now see it should be 0 to 10,000,000.
As rand() will give an answer of at least 15 bits, call rand() multiple times, shift by 15 and XOR the results. Finally mod by 10,000,001.
unsigned long x;
x = rand();
x <<= 15;
x ^= rand();
x %= 10000001;
The distribution is very flat, but does introduce a very small bias. After 32768*32768 iterations, each value of x 0 to 10,000,000 to occur about 107.37 times. Instead they range from 107 to 108 times.
Combining multiple rand() call results with +, * or | will cause a significant bias in the distribution of the results.
[Edit]
RAND_MAX is 32767 (0x7FFF) for OP's platform. The C spec says "value of the RAND_MAX macro shall be at least 32767". Because RAND_MAX may be longer than 15 bits, it is important to use the ^ operator above rather than | for this code when used on other platforms.
Calculate with % 1000001 if you want numbers between 0 and 1000000.
Also RAND_MAX is conly guaranteed to be at least 32767
int main(){
int i, x;
srand(time(NULL));
for(i=0; i<10000; i++){
x = (rand() * rand()) % 1000001;
printf("%d\n",x);
}
return 0;
}
Use this function, it will give you random number between two number (min and max) :
unsigned long int my_rand (unsigned long int Min, unsigned long int Max)
{
static int first = 0;
if (first == 0)
{
srand (time (NULL)); //initialize generator of random number
first = 1;
}
return ((unsigned long int)(rand() * (Max+1 - Min) / RAND_MAX + Min));
}