[英]how to generate random values with uniform intervals in c within a set range
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? 但是,如果我的范围是(0,100),那么如何使它返回的随机值始终是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? 每次调用时,如何使RANDOM_NUM变量始终为20/3的倍数? This one generates a random float value between 0 and 1. (that is uniform intervals) 这会产生一个介于0和1之间的随机浮点值(即均匀的间隔)。
RANDOM_NUM = ((float)rand()/(float)(RAND_MAX+1));
但是,如果我的范围是(0,100),那么如何使它返回的随机值始终是8的倍数呢?
return ((result % range + Min)/8)*8;
"How can I make the RANDOM_NUM
variable to always be a multiple of 20/3 every time I call it?" “如何使每次调用RANDOM_NUM
变量始终为20/3的倍数?”
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. 由于此程序精度更高,所以我优先使用double
来进行float
运算,但即使如此,也不能保证精确倍数,如该程序所示。 When tested, in some cases the remainder is 0, in the others it is apparently, and absurdly 6.666667, which is 20/3. 经过测试,在某些情况下,余数为0,在其他情况下,显然为余数, 荒谬的是 6.666667,即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~~
. 在小数点表示法中,除法1/3的结果具有递归的一位数字0.333333~
,在二进制点表示法中具有递归的两位数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
Assuming that rand is your random integer between 0 and 100 : 假设rand是0到100之间的随机整数:
rand = rand - (rand % 8); rand = rand-(rand%8);
The fastest solution would be to just set the three lowest bits of the integer to zero: rand &= ~0x07
. 最快的解决方案是将整数的三个最低位设置为零: rand &= ~0x07
。 (Assuming that rand
is an integer between 0 and 100.) (假设rand
是0到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). 当然,如果您希望它是不是2的幂的数字的倍数,那么这将不适用,如果您不熟悉位运算(注释不会受到伤害),则很难阅读。
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]. 您可以获取0-13范围内的随机数,然后将结果乘以8。结果将在[0,104]范围内。 You could do the same thing for 20/3. 您可以为20/3做同样的事情。 Assuming you only take integer results, which appears to be true, this would always work. 假设您只取整数结果(看起来是正确的),那么它将始终有效。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.