awk: rand() could return 1.0, fix this - should be in [0,1)

While at it, make it finer-grained (63 bits of randomness)

function                                             old     new   delta
evaluate                                            3303    3336     +33
.rodata                                           104107  104111      +4
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 2/0 up/down: 37/0)               Total: 37 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
Denys Vlasenko 2021-07-02 19:38:03 +02:00
parent 37ae8cdc6e
commit 8bb03da906

View File

@ -3118,9 +3118,20 @@ static var *evaluate(node *op, var *res)
case F_rn: /*rand*/ case F_rn: /*rand*/
if (op1) if (op1)
syntax_error("Too many arguments"); syntax_error("Too many arguments");
R_d = (double)rand() / (double)RAND_MAX; {
#if RAND_MAX >= 0x7fffffff
uint32_t u = ((uint32_t)rand() << 16) ^ rand();
uint64_t v = ((uint64_t)rand() << 32) | u;
/* the above shift+or is optimized out on 32-bit arches */
# if RAND_MAX > 0x7fffffff
v &= 0x7fffffffffffffffUL;
# endif
R_d = (double)v / 0x8000000000000000UL;
#else
# error Not implemented for this value of RAND_MAX
#endif
break; break;
}
case F_co: case F_co:
if (ENABLE_FEATURE_AWK_LIBM) { if (ENABLE_FEATURE_AWK_LIBM) {
R_d = cos(L_d); R_d = cos(L_d);