hossein
hossein

Reputation: 356

How to generate random numbers between 0 and 1 in bash

I'm trying to infer how to generate two random numbers as input values for parameters of readproportion, updateproportion in a way that sum of these parameters should equal 1, in the following bash command.

$ ./bin/ycsb run basic -P workloads/workloada -p readproportion=0.50 -p updateproportion=0.50

Please help with your suggestions.

Thanks

Upvotes: 3

Views: 12024

Answers (6)

TJR
TJR

Reputation: 3773

This works nice

$ bc -l <<< "scale=16; $(od -t u2 -An -N2 /dev/random)/(2 ^ 16)"
.2792053222656250

Upvotes: 1

Phil Rutschman
Phil Rutschman

Reputation: 552

This is "wasteful" (it just throws away characters until /dev/urandom happens to spit out enough ascii 0 to 9s), but it is securely pseudorandom:

rand_frac() { echo -n 0.; LANG=C tr -dc 0-9 </dev/urandom | head -c12; }

Then, you can

$ echo The random number is.... $(rand_frac)
The random number is.... 0.413856349581

LANG=C is there to prevent tr from choking on bad UTF-8 sequences from /dev/urandom. -dc means delete the compliment of the subsequent character class (so, delete everything except 0-9).

You can change the 0-9 to generate arbitrary character classes, or adjust head -c 12 to something else, which can be useful for making passwords.

Upvotes: 1

Ed Morton
Ed Morton

Reputation: 203129

$ arr=( $(awk 'BEGIN{srand(); r=rand(); print r, 1-r}') )
$ echo "${arr[0]}"
0.661624
$ echo "${arr[1]}"
0.338376

$ arr=( $(awk 'BEGIN{srand(); r=rand(); printf "%.2f %.2f\n", r, 1-r}') )
$ echo "${arr[0]}"
0.74
$ echo "${arr[1]}"
0.26

srand() will only update the seed once per second but as long as you don't need to call the script more frequently than once per second it should be fine.

Upvotes: 2

Cyrus
Cyrus

Reputation: 88543

With idea from Robert J:

RANDOM=$$                      # Reseed using script's PID
r1=$((${RANDOM}%98+1))
r2=$((100-$r1))
printf -v r1 "0.%.2d" $r1
printf -v r2 "0.%.2d" $r2
echo "$r1 $r2"

Output (e.g.):

0.66 0.34
0.01 0.99
0.42 0.58
0.33 0.67
0.22 0.78
0.33 0.67
0.65 0.35
0.77 0.23
0.71 0.29

Upvotes: 1

Robert J
Robert J

Reputation: 310

Here is a super simple way to do it:

echo 0."$RANDOM"

^^ DO NOT USE AND READ BELOW ^^

Edit:

I cannot read:

$ rnum=$((RANDOM%10000+1))
$ echo "scale=4; $rnum/10000" | bc
.8748
$ echo "scale=4; 1-$rnum/10000" | bc
.1252

Edit 2:

As pointed out the first iteration of this is terrible. Once I read the issue entirely and tried to do some simple maths with the "number". I realized that this is super broken. You can read more at:

http://www.tldp.org/LDP/abs/html/randomvar.html - and - https://www.shell-tips.com/2010/06/14/performing-math-calculation-in-bash/

Upvotes: 1

mauro
mauro

Reputation: 5940

As far as I can remember ${RANDOM} generates integers in the interval 0 - 32767. So, I guess, you might want to try something like this to generate random values in [0,1]:

bc -l <<< "scale=4 ; ${RANDOM}/32767"

Upvotes: 8

Related Questions