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;
}
Related
This question already has answers here:
What is the behavior of integer division?
(6 answers)
Closed 10 months ago.
I am calculating salary by inflation
By random 1 to 5% the salary increase.
For exam, in 2020 inflation increased by 2%. And my salary is 1000.
Then answer should be 1000 * 1.02 = 1020.
So I made a simple code
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(void) {
srand((unsigned int)time(NULL));
int inc_rate = (rand() % 5) + 1;
float num = (100 + inc_rate) / 100;
printf("%d \n", inc_rate);
printf("%f", 100 * (float)num);
return 0;
}
But if I run it cannot count 1.02.
For example the outcomes
2
100.000000
How can I calculate division by C
The operator "/" performs integer division if both operands are integers (the fractional part is discarded). This means that the expression
(100 + inc_rate) / 100
will always be one if inc_rate is an integer between one and five.
Try this instead:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(void)
{
srand(time(NULL));
int inc_rate = (rand() % 5) + 1;
float num = (100.0 + inc_rate) / 100.0;
printf("%d\n", inc_rate);
printf("%f\n", 100.0 * num);
return 0;
}
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);
}
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));
}
This question already has answers here:
How to generate a random integer number from within a range
(11 answers)
Closed 9 years ago.
How do I go about generating random integer values between a range (in this case 1-12 including 1 and 12) in the C language?
I've read about seeding (srand()) and using rand() within a range but am unsure about how to go about it.
Edit: Here is what I have so far
# include <stdio.h>
# include <stdlib.h>
# include <time.h>
// Craps Program
// Written by Kane Charles
// Lab 2 - Task 2
// 7 or 11 indicates instant win
// 2, 3 or 12 indicates instant los
// 4, 5, 6, 8, 9, 10 on first roll becomes "the point"
// keep rolling dice until either 7 or "the point is rolled"
// if "the point" is rolled the player wins
// if 7 is rolled then the player loses
int wins = 0, losses = 0;
int r, i;
int N = 1, M = 12;
int randomgenerator();
main(void){
/* initialize random seed: */
srand (time(NULL));
/* generate random number 10,000 times: */
for(i=0; i < 10000 ; i++){
int r = randomgenerator();
if (r = 7 || 11) {
wins++;
}
else if (r = 2 || 3 || 12) {
losses++;
}
else if (r = 4 || 5 || 6 || 8 || 9 || 10) {
int point = r;
int temproll;
do
{
int temproll = randomgenerator();
}while (temproll != 7 || point);
if (temproll = 7) {
losses++;
}
else if (temproll = point) {
wins++;
}
}
}
printf("Wins\n");
printf("%lf",&wins);
printf("\nLosses\n");
printf("%lf",&losses);
}
int randomgenerator(){
r = M + rand() / (RAND_MAX / (N - M + 1) + 1);
return r;
}
The simple way is
#include <stdlib.h>
#include <sys/time.h>
int main(void)
{
struct timeval t1;
gettimeofday(&t1, NULL);
srand(t1.tv_usec * t1.tv_sec);
int a = 1, b = 12;
int val = a + (b-a) * (double)rand() / (double)RAND_MAX + 0.5;
return 0;
}
Edit, since someone asked: You really do have to use floating point arithmetic to get this to come out right (or as right as it can given rand()'s limitations such as they are). Any solution which relies purely on integer arithmetic and rand() will of necessity use \ or %, and when this happens you will get roundoff error--where c and d are declared int and c = 5 and d = 2, for example, c/d == 2 and d/c == 0. When comes to sampling from a range, what happens is that in compressing the range [0, RAND_MAX] to [a, b], you have to do some kind of division operation since the former is so much larger than the latter. Then roundoff creates bias (unless you get really lucky and things evenly divide). Not a truly thorough explanation but I hope that conveys the idea.
You should use: M + rand() / (RAND_MAX / (N - M + 1) + 1)
Don't use rand() % N (which tries to return numbers from 0 to N-1). It is poor, because the low-order bits of many random number generators are distressingly non-random. (See question 13.18.)
Example code:
#include <stdio.h> /* printf, scanf, puts, NULL */
#include <stdlib.h> /* srand, rand */
#include <time.h> /* time */
int main ()
{
int r, i;
int M = 1,
N = 12;
/* initialize random seed: */
srand (time(NULL));
/* generate number between 1 and 12: */
for(i=0; i < 10 ; i++){
r = M + rand() / (RAND_MAX / (N - M + 1) + 1);
printf("\n%d", r);
}
printf("\n") ;
return EXIT_SUCCESS;
}
It's working here at codepad.