Ensure that Math.random() really covers [0,1) interval (#1417)
Legacy implementation made incorrect assumptions on how many bits of useful information is returned by libc's `rand()`. If `RAND_MAX` had more than 16 useful bits, it assumed that `rand()` could return 32 useful random bits. However, e.g., jerry-libc's `RAND_MAX` is `0x7fffffff`, which denotes 31 useful bits only. The consequence was that `Math.random()` covered only the lower half of the standard-mandated `[0,1)` interval. This path fixes the error and always uses the exact value of `RAND_MAX` to compute the random value, which will thus fully cover `[0,1)`. Fixes #1414 JerryScript-DCO-1.0-Signed-off-by: Akos Kiss akiss@inf.u-szeged.hu
This commit is contained in:
@@ -507,28 +507,11 @@ static ecma_value_t
|
|||||||
ecma_builtin_math_object_random (ecma_value_t this_arg) /**< 'this' argument */
|
ecma_builtin_math_object_random (ecma_value_t this_arg) /**< 'this' argument */
|
||||||
{
|
{
|
||||||
JERRY_UNUSED (this_arg);
|
JERRY_UNUSED (this_arg);
|
||||||
uint32_t rnd = 1;
|
|
||||||
uint32_t reps_count;
|
|
||||||
#if RAND_MAX < 0x100
|
|
||||||
reps_count = 4;
|
|
||||||
#elif RAND_MAX < 0x10000
|
|
||||||
reps_count = 2;
|
|
||||||
#else /* RAND_MAX >= 0x10000 */
|
|
||||||
reps_count = 1;
|
|
||||||
#endif /* RAND_MAX < 0x100 */
|
|
||||||
|
|
||||||
for (uint32_t i = 0; i < reps_count; i++)
|
const ecma_number_t rand_max = (ecma_number_t) RAND_MAX;
|
||||||
{
|
const ecma_number_t rand_max_min_1 = (ecma_number_t) (RAND_MAX - 1);
|
||||||
uint32_t next_rand = (uint32_t) rand ();
|
|
||||||
rnd *= next_rand;
|
|
||||||
}
|
|
||||||
|
|
||||||
const uint32_t max_uint32 = (uint32_t) -1;
|
return ecma_make_number_value (((ecma_number_t) rand ()) / rand_max * rand_max_min_1 / rand_max);
|
||||||
ecma_number_t rand = (ecma_number_t) rnd;
|
|
||||||
rand /= (ecma_number_t) max_uint32;
|
|
||||||
rand *= (ecma_number_t) (max_uint32 - 1) / (ecma_number_t) max_uint32;
|
|
||||||
|
|
||||||
return ecma_make_number_value (rand);
|
|
||||||
} /* ecma_builtin_math_object_random */
|
} /* ecma_builtin_math_object_random */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user