aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2021-07-02 19:38:03 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2021-07-02 19:38:03 +0200
commit8bb03da906e1f8f750123214b15a19d7d4e166c1 (patch)
treea36a7ca749f028149c5f112eb792acbfc0779f78
parent37ae8cdc6e428e68ad76f6b446881ecff305ebd3 (diff)
downloadbusybox-w32-8bb03da906e1f8f750123214b15a19d7d4e166c1.tar.gz
busybox-w32-8bb03da906e1f8f750123214b15a19d7d4e166c1.tar.bz2
busybox-w32-8bb03da906e1f8f750123214b15a19d7d4e166c1.zip
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>
-rw-r--r--editors/awk.c15
1 files changed, 13 insertions, 2 deletions
diff --git a/editors/awk.c b/editors/awk.c
index 8d7777ca6..64fe81be4 100644
--- a/editors/awk.c
+++ b/editors/awk.c
@@ -3118,9 +3118,20 @@ static var *evaluate(node *op, var *res)
3118 case F_rn: /*rand*/ 3118 case F_rn: /*rand*/
3119 if (op1) 3119 if (op1)
3120 syntax_error("Too many arguments"); 3120 syntax_error("Too many arguments");
3121 R_d = (double)rand() / (double)RAND_MAX; 3121 {
3122#if RAND_MAX >= 0x7fffffff
3123 uint32_t u = ((uint32_t)rand() << 16) ^ rand();
3124 uint64_t v = ((uint64_t)rand() << 32) | u;
3125 /* the above shift+or is optimized out on 32-bit arches */
3126# if RAND_MAX > 0x7fffffff
3127 v &= 0x7fffffffffffffffUL;
3128# endif
3129 R_d = (double)v / 0x8000000000000000UL;
3130#else
3131# error Not implemented for this value of RAND_MAX
3132#endif
3122 break; 3133 break;
3123 3134 }
3124 case F_co: 3135 case F_co:
3125 if (ENABLE_FEATURE_AWK_LIBM) { 3136 if (ENABLE_FEATURE_AWK_LIBM) {
3126 R_d = cos(L_d); 3137 R_d = cos(L_d);