Fix IRandomBetween returning out-of-range numbers (#173)
This commit is contained in:
parent
f1849412e9
commit
b7da8770b4
|
@ -195,8 +195,14 @@ int IRandomBetween(int pA, int pB) {
|
|||
int num;
|
||||
char s[32];
|
||||
|
||||
num = (pB + 1 - pA) * (rand() / (double)RAND_MAX) + pA;
|
||||
return num;
|
||||
num = rand();
|
||||
#if RAND_MAX == 0x7fff
|
||||
// If RAND_MAX == 0x7fff, then `num` can be seen as a fixed point number with 15 fractional and 17 integral bits
|
||||
return pA + ((num * (pB + 1 - pA)) >> 15);
|
||||
#else
|
||||
// If RAND_MAX != 0x7fff, then use floating numbers (alternative is using modulo)
|
||||
return pA + (int)((pB + 1 - pA) * (num / ((float)RAND_MAX + 1)));
|
||||
#endif
|
||||
}
|
||||
|
||||
// IDA: int __usercall PercentageChance@<EAX>(int pC@<EAX>)
|
||||
|
|
|
@ -96,10 +96,36 @@ void test_utility_PathCat() {
|
|||
}
|
||||
|
||||
void test_utility_IRandomBetween() {
|
||||
tU32 source_y_delta;
|
||||
int r;
|
||||
int i;
|
||||
int j;
|
||||
int actual_min;
|
||||
int actual_max;
|
||||
struct {
|
||||
int min;
|
||||
int max;
|
||||
} ranges[] = {
|
||||
{ -2, 1 },
|
||||
{ 1, -2 },
|
||||
{ 2, -1 },
|
||||
{ -1, 2 },
|
||||
{ 0, 3 },
|
||||
{ 3, 0 },
|
||||
{ 0, 10000 },
|
||||
{ 10000, 0 },
|
||||
};
|
||||
|
||||
source_y_delta = ((66 << 16) / 67) - 0x10000;
|
||||
printf("delta %x, %x\n", source_y_delta, source_y_delta >> 16);
|
||||
for (i = 0; i < BR_ASIZE(ranges); i++) {
|
||||
LOG_INFO("Testing min=%d max=%d", ranges[i].min, ranges[i].max);
|
||||
actual_min = MIN(ranges[i].min, ranges[i].max);
|
||||
actual_max = MAX(ranges[i].min, ranges[i].max);
|
||||
for (j = 0; j < 1000; j++) {
|
||||
r = IRandomBetween(ranges[i].min, ranges[i].max);
|
||||
|
||||
TEST_ASSERT_GREATER_OR_EQUAL(actual_min, r);
|
||||
TEST_ASSERT_LESS_OR_EQUAL(actual_max, r);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void test_utility_suite() {
|
||||
|
|
Loading…
Reference in New Issue