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.
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 trying to generate 12 digit random numbers in C, but it's always generating 10 digit numbers.
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
void main()
{
srand(time(NULL));
long r = rand();
r = r*100;
printf("%ld",r);
}
rand() returns an int value in the range of [0...RAND_MAX]
Based on the C spec, RAND_MAX >= 32767 and RAND_MAX <= INT_MAX.
Call rand() multiple times to create a wide value
unsigned long long rand_atleast12digit(void) {
unsigned long long r = rand();
#if RAND_MAX >= 999999999999
#elif RAND_MAX >= 999999
r *= RAND_MAX + 1ull;
r += rand();
#else
r *= RAND_MAX + 1ull;
r += rand();
r *= RAND_MAX + 1ull;
r += rand();
#endif
return r;
}
The above returns a number if the range of 0 to at least 999,999,999,999. To reduce that to only that range, code could use return r % 1000000000000;.
Using % likely does not create an balanced distribution of random numbers. Other posts address details of how to cope with that like this good one incorporated as follows.
#if RAND_MAX >= 999999999999
#define R12DIGIT_DIVISOR (RAND_MAX/1000000000000)
#elif RAND_MAX >= 999999
#define RAND_MAX_P1 (RAND_MAX+1LLU)
#define R12DIGIT_DIVISOR ((RAND_MAX_P1*RAND_MAX_P1-1)/1000000000000)
#else
#define RAND_MAX_P1 (RAND_MAX+1LLU)
#define R12DIGIT_DIVISOR ((RAND_MAX_P1*RAND_MAX_P1*RAND_MAX_P1-1)/1000000000000)
#endif
unsigned long long rand_12digit(void) {
unsigned long long retval;
do {
retval = rand_atleast12digit() / R12DIGIT_DIVISOR;
} while (retval == 1000000000000);
return retval;
}
Note that the quality of rand() is not well defined, so repeated calls may not provide high quality results.
OP's code fails if long is 32-bit as it lacks range for a 12 decimal digit values. #Michael Walz
If long is wide enough, *100 will always make the least 2 decimal digits 00 - not very random. #Alexei Levenkov
long r = rand();
r = r*100;
The result of rand is int, which means you can't get a 12 digit number directly from it.
If you need value that is always 12 digits you need to make sure values fit in particular range.
Sample below assumes that you need just some of the numbers to be 12 digits - you just need 8 extra bits - so shifting and OR'ing results would produce number in 0x7fffffffff-0 range that would often result up to 12 digit output when printed as decimal:
r = rand();
r = (r << 8) | rand();
PS: Make sure the variable that will store the result is big enough to store the 12 digit number.
My simple way to generate random strings or numbers is :
static char *ws_generate_token(size_t length) {
static char charset[] = "1234567890"; // generate numbers only
//static char charset[] = "abcdefghijklmnopqrstuvwxyz1234567890"; to generate random string
char *randomString = NULL;
if (length) {
randomString = malloc(sizeof(char) * (length + 1));
if (randomString) {
for (int n = 0; n < length; n++) {
int key = rand() % (int)(sizeof(charset) -1);
randomString[n] = charset[key];
}
randomString[length] = '\0';
}
}
return randomString;
}
Explain the code
Create an array of chars which will contains (numbers, alphabets ...etc)
Generate a random number between [0, array length], let's name it X.
Get the character at random X position in the array of chars.
finally, add this character to the sequence of strings (or numbers) you want to have in return.
How to use it ?
#define TOKEN_LENGTH 12
char *token;
token = ws_generate_token(TOKEN_LENGTH);
conversion from string to int
int token_int = atol(token);
dont forget !
free(token); // free the memory when you finish
#include <stdio.h>
#include <stdlib.h>
int main()
{
int i, n;
time_t t;
n = 5;
/* Intializes random number generator int range */
srand((unsigned) time(&t));
/* Print 5 random numbers from 50 to back
for( i = 0 ; i < n ; i++ )
{
printf("%d\n", rand() % 50);
}
return(0);
}
I'm trying to generate a random floating point number in between 0 and 1 (whether it's on [0,1] or [0,1) shouldn't matter for me). Every question online about this seems to involves the rand() call, seeded with time(NULL), but I want to be able to invoke my program more than once a second and get different random numbers every time. This lead me to the getrandom syscall in Linux, which pulls from /dev/urandom. I came up with this:
#include <stdio.h>
#include <sys/syscall.h>
#include <unistd.h>
#include <stdint.h>
int main() {
uint32_t r = 0;
for (int i = 0; i < 20; i++) {
syscall(SYS_getrandom, &r, sizeof(uint32_t), 0);
printf("%f\n", ((double)r)/UINT32_MAX);
}
return 0;
}
My question is simply whether or not I'm doing this correctly. It appears to work, but I'm worried that I'm misusing something, and there are next to no examples using getrandom() online.
OP has 2 issues:
How to started the sequence very randomly.
How to generate a double on the [0...1) range.
The usual method is to take a very random source like /dev/urandom or the result from the syscall() or maybe even seed = time() ^ process_id; and seed via srand(). Then call rand() as needed.
Below includes a quickly turned method to generate a uniform [0.0 to 1.0) (linear distribution). But like all random generating functions, really good ones are base on extensive study. This one simply calls rand() a few times based on DBL_MANT_DIG and RAND_MAX,
[Edit] Original double rand_01(void) has a weakness in that it only generates a 2^52 different doubles rather than 2^53. It has been amended. Alternative: a double version of rand_01_ld(void) far below.
#include <assert.h>
#include <float.h>
#include <limits.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
double rand_01(void) {
assert(FLT_RADIX == 2); // needed for DBL_MANT_DIG
unsigned long long limit = (1ull << DBL_MANT_DIG) - 1;
double r = 0.0;
do {
r += rand();
// Assume RAND_MAX is a power-of-2 - 1
r /= (RAND_MAX/2 + 1)*2.0;
limit = limit / (RAND_MAX/2 + 1) / 2;
} while (limit);
// Use only DBL_MANT_DIG (53) bits of precision.
if (r < 0.5) {
volatile double sum = 0.5 + r;
r = sum - 0.5;
}
return r;
}
int main(void) {
FILE *istream = fopen("/dev/urandom", "rb");
assert(istream);
unsigned long seed = 0;
for (unsigned i = 0; i < sizeof seed; i++) {
seed *= (UCHAR_MAX + 1);
int ch = fgetc(istream);
assert(ch != EOF);
seed += (unsigned) ch;
}
fclose(istream);
srand(seed);
for (int i=0; i<20; i++) {
printf("%f\n", rand_01());
}
return 0;
}
If one wanted to extend to an even wider FP, unsigned wide integer types may be insufficient. Below is a portable method that does not have that limitation.
long double rand_01_ld(void) {
// These should be calculated once rather than each function call
// Leave that as a separate implementation problem
// Assume RAND_MAX is power-of-2 - 1
assert((RAND_MAX & (RAND_MAX + 1U)) == 0);
double rand_max_p1 = (RAND_MAX/2 + 1)*2.0;
unsigned BitsPerRand = (unsigned) round(log2(rand_max_p1));
assert(FLT_RADIX != 10);
unsigned BitsPerFP = (unsigned) round(log2(FLT_RADIX)*LDBL_MANT_DIG);
long double r = 0.0;
unsigned i;
for (i = BitsPerFP; i >= BitsPerRand; i -= BitsPerRand) {
r += rand();
r /= rand_max_p1;
}
if (i) {
r += rand() % (1 << i);
r /= 1 << i;
}
return r;
}
If you need to generate doubles, the following algorithm could be of use:
CPython generates random numbers using the following algorithm (I changed the function name, typedefs and return values, but algorithm remains the same):
double get_random_double() {
uint32_t a = get_random_uint32_t() >> 5;
uint32_t b = get_random_uint32_t() >> 6;
return (a * 67108864.0 + b) * (1.0 / 9007199254740992.0);
}
The source of that algorithm is a Mersenne Twister 19937 random number generator by Takuji Nishimura and Makoto Matsumoto. Unfortunately the original link mentioned in the source is not available for download any longer.
The comment on this function in CPython notes the following:
[this function] is the function named genrand_res53 in the original code;
generates a random number on [0,1) with 53-bit resolution; note that
9007199254740992 == 2**53; I assume they're spelling "/2**53" as
multiply-by-reciprocal in the (likely vain) hope that the compiler will
optimize the division away at compile-time. 67108864 is 2**26. In
effect, a contains 27 random bits shifted left 26, and b fills in the
lower 26 bits of the 53-bit numerator.
The orginal code credited Isaku Wada for this algorithm, 2002/01/09
Simplifying from that code, if you want to create a float fast, you should mask the bits of uint32_t with (1 << FLT_MANT_DIG) - 1 and divide by (1 << FLT_MANT_DIG) to get the proper [0, 1) interval:
#include <stdio.h>
#include <sys/syscall.h>
#include <unistd.h>
#include <stdint.h>
#include <float.h>
int main() {
uint32_t r = 0;
float result;
for (int i = 0; i < 20; i++) {
syscall(SYS_getrandom, &r, sizeof(uint32_t), 0);
result = (float)(r & ((1 << FLT_MANT_DIG) - 1)) / (1 << FLT_MANT_DIG);
printf("%f\n", result);
}
return 0;
}
Since it can be assumed that your Linux has a C99 compiler, we can use ldexpf instead of that division:
#include <math.h>
result = ldexpf(r & ((1 << FLT_MANT_DIG) - 1), -FLT_MANT_DIG);
To get the closed interval [0, 1], you can do the slightly less efficient
result = ldexpf(r % (1 << FLT_MANT_DIG), -FLT_MANT_DIG);
To generate lots of good quality random numbers fast, I'd just use the system call to fetch enough data to seed a PRNG or CPRNG, and proceed from there.
unsigned const number = minimum + (rand() % (maximum - minimum + 1))
I know how to (easily) generate a random number within a range such as from 0 to 100. But what about a random number from the full range of int (assume sizeof(int) == 4), that is from INT_MIN to INT_MAX, both inclusive?
I don't need this for cryptography or the like, but a approximately uniform distribution would be nice, and I need a lot of those numbers.
The approach I'm currently using is to generate 4 random numbers in the range from 0 to 255 (inclusive) and do some messy casting and bit manipulations. I wonder whether there's a better way.
On my system RAND_MAX is 32767 which is 15 bits. So for a 32-bit unsigned just call three times and shift, or, mask etc.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(void){
unsigned rando, i;
srand((unsigned)time(NULL));
for (i = 0; i < 3; i++) {
rando = ((unsigned)rand() << 17) | ((unsigned)rand() << 2) | ((unsigned)rand() & 3);
printf("%u\n", rando);
}
return 0;
}
Program output:
3294784390
3748022412
4088204778
For reference I'm adding what I've been using:
int random_int(void) {
assert(sizeof(unsigned int) == sizeof(int));
unsigned int accum = 0;
size_t i = 0;
for (; i < sizeof(int); ++i) {
i <<= 8;
i |= rand() & 0x100;
}
// Attention: Implementation defined!
return (int) accum;
}
But I like Weather Vane's solution better because it uses fewer rand() calls and thus makes more use of the (hopefully good) distribution generated by it.
We should be able to do something that works no matter what the range of rand() or what size result we're looking for just by accumulating enough bits to fill a given type:
// can be any unsigned type.
typedef uint32_t uint_type;
#define RAND_UINT_MAX ((uint_type) -1)
uint_type rand_uint(void)
{
// these are all constant and factor is likely a power of two.
// therefore, the compiler has enough information to unroll
// the loop and can use an immediate form shl in-place of mul.
uint_type factor = (uint_type) RAND_MAX + 1;
uint_type factor_to_k = 1;
uint_type cutoff = factor ? RAND_UINT_MAX / factor : 0;
uint_type result = 0;
while ( 1 ) {
result += rand() * factor_to_k;
if (factor_to_k <= cutoff)
factor_to_k *= factor;
else
return result;
}
}
Note: Makes the minimum number of calls to rand() necessary to populate all bits.
Let's verify this gives a uniform distribution.
At this point we could just cast the result of rand_uint() to type int and be done, but it's more useful to get output in a specified range. The problem is: How do we reach INT_MAX when the operands are of type int?
Well... We can't. We'll need to use a type with greater range:
int uniform_int_distribution(int min, int max)
{
// [0,1) -> [min,max]
double canonical = rand_uint() / (RAND_UINT_MAX + 1.0);
return floor(canonical * (1.0 + max - min) + min);
}
As a final note, it may be worthwhile to implement the random function in terms of type double instead, i.e., accumulate enough bits for DBL_MANT_DIG and return a result in the range [0,1). In fact this is what std::generate_canonical does.
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));
}