1

So far I have a function which generates a random integer value within a fixed range (Min, Max) and it seems to work. But how can I make it so that if my range was (0,100), the random values returned is always a multiple of 8? (that is uniform intervals)

int generate_rand(int Min, int Max)
{
// Generates random number between min and max, inclusive.

int range, result, cutoff;

if (Min >= Max)
    return Min; // only one outcome possible, or invalid parameters
range = Max-Min+1;
cutoff = (RAND_MAX / range) * range;

// Rejection method, to be statistically unbiased.
do {
    result = rand();
} while (result >= cutoff);

return result % range + Min;
}

The same for the code below. How can I make the RANDOM_NUM variable to always be a multiple of 20/3 every time I call it? This one generates a random float value between 0 and 1. (that is uniform intervals)

 RANDOM_NUM = ((float)rand()/(float)(RAND_MAX+1));
3
  • 0 to 100 with a multiple of 8. Hmm that 12.5 intervals. Commented Feb 3, 2015 at 16:29
  • A potential problem with Max-Min+1 is that the result may readily overflow. Commented Feb 3, 2015 at 16:32
  • Note: ((float)rand()/(float)(RAND_MAX+1)) may generate 0.0, but it will not generate 1.0. IOWs [0.0, 1.0) - not exactly a "value between 0 and 1". Commented Feb 3, 2015 at 16:34

5 Answers 5

1

But how can I make it so that if my range was (0,100), the random values returned is always a multiple of 8?

return ((result % range + Min)/8)*8;
Sign up to request clarification or add additional context in comments.

Comments

1

"How can I make the RANDOM_NUM variable to always be a multiple of 20/3 every time I call it?"

I used double in preference to float due to its greater precision, but even so there cannot be a guarantee of an exact multiple, as this program shows. When tested, in some cases the remainder is 0, in the others it is apparently, and absurdly 6.666667, which is 20/3. This is due to the fact that not all numbers can be precisely represented in floating point format.

In decimal point notation the result of the division 1/3 has a recurrent one digit 0.333333~ which in binary point notation has a recurrent 2 digits 0.010101~~.

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>

#define NUMERATOR   20
#define DENOMINATOR 3

double randnum(int numerator, int denominator) {
    return (double)rand() * (double)numerator / (double)denominator;
}

int main(void) {
    int i;
    double random_num, remainder;
    srand ((unsigned)time(NULL));
    for (i=0; i<10; i++) {
        random_num = randnum(NUMERATOR, DENOMINATOR);
        remainder = fmod(random_num, (double)NUMERATOR / (double)DENOMINATOR);
        printf("%-16f %f\n", random_num, remainder);
    }
    return 0;
}

Program output (random number, remainder):

72706.666667     0.000000
209733.333333    0.000000
170686.666667    6.666667
187546.666667    6.666667
121093.333333    6.666667
116660.000000    6.666667
75646.666667     0.000000
64960.000000     6.666667
186653.333333    0.000000
159713.333333    0.000000

Comments

0

Assuming that rand is your random integer between 0 and 100 :

rand = rand - (rand % 8);

Comments

0

The fastest solution would be to just set the three lowest bits of the integer to zero: rand &= ~0x07. (Assuming that rand is an integer between 0 and 100.)

Of course that does not apply if you want it to be multiple of a number that is not a power of two and it is hard to read if you're not familiar with bit operations (a comment could not hurt).

Comments

0

You could get a random number in the range 0-13 and then multiply your result by 8. It would be in the range [0, 104]. You could do the same thing for 20/3. Assuming you only take integer results, which appears to be true, this would always work.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.