diff options
author | Denys Vlasenko | 2021-07-02 19:38:03 +0200 |
---|---|---|
committer | Denys Vlasenko | 2021-07-02 19:38:03 +0200 |
commit | 8bb03da906e1f8f750123214b15a19d7d4e166c1 (patch) | |
tree | a36a7ca749f028149c5f112eb792acbfc0779f78 /editors/awk.c | |
parent | 37ae8cdc6e428e68ad76f6b446881ecff305ebd3 (diff) | |
download | busybox-8bb03da906e1f8f750123214b15a19d7d4e166c1.zip busybox-8bb03da906e1f8f750123214b15a19d7d4e166c1.tar.gz |
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>
Diffstat (limited to 'editors/awk.c')
-rw-r--r-- | editors/awk.c | 15 |
1 files changed, 13 insertions, 2 deletions
diff --git a/editors/awk.c b/editors/awk.c index 8d7777c..64fe81b 100644 --- a/editors/awk.c +++ b/editors/awk.c @@ -3118,9 +3118,20 @@ static var *evaluate(node *op, var *res) case F_rn: /*rand*/ if (op1) 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; - + } case F_co: if (ENABLE_FEATURE_AWK_LIBM) { R_d = cos(L_d); |