Lord of Strandhill
Lord of Strandhill

Reputation: 25

Bash Generate a random number between a positive and a negative

I have to write a Program, which shows some words on an image which are randomly rotated. I would like these to be between e.g -30 and 30 ° . But I didn't found any command in bash/UNIX, that could generate a random number between a positive and a negative.

Thanks for your help.

Upvotes: 1

Views: 5134

Answers (3)

Alfred.37
Alfred.37

Reputation: 149

Or generate a random number in a range, which can be positive or negative, on follow way:

getRand(){
    min="${1:-1}"   ## min is the first parameter, or 1 if no parameter is given           
    max="${2:-100}" ## max is the second parameter, or 100 if no parameter is given
    rnd_count=$((RANDOM%(max-min+1)+min)); #
    echo "$rnd_count"
}

var=$(getRand -10 123)
echo $var

For bigger range and more random random, replace the RANDOM by SRANDOM. For this you need to update your terminal to version 5.1 at minimum, which is available since end of year 2020.

Upvotes: 2

gboffi
gboffi

Reputation: 25023

The correct approach (no external processes are spawned) was already presented by @Barmar in a comment.

Should the OP need it unraveled, here it is:

angle=$(($RANDOM%61-30))

but I'd like to suggest a worse alternative, as someone said "Worse is better"

angle=$(seq -30 30 | shuf -n 1) 
  • seq puts to stdout a sequence of integers, newline separated,
  • shuf shuffles randomly its input,
    • the -n 1 option means output just the first randomly shuffled line,

so that we have that we generate a deck of cards, numbered -30+30, we shuffle the deck and we deal just the 1st card.

What I like in my answer is that the range of the solution is stated more clearly, at least from the POV of a non mathematically endowed person.

On the contrary it is SLOWER than using $RANDOM

10:31 boffi@debian:~ $ time for i in {1..10000} ; do echo > /dev/null ; done

real    0m0.077s
user    0m0.036s
sys     0m0.040s
10:32 boffi@debian:~ $ time for i in {1..10000} ; do echo $(($RANDOM%61-30)) > /dev/null ; done

real    0m0.138s
user    0m0.116s
sys     0m0.020s
10:32 boffi@debian:~ $ time for i in {1..10000} ; do echo $(seq -30 30|shuf -n 1) > /dev/null ; done

real    0m33.328s
user    0m0.372s
sys     0m4.560s
10:33 boffi@debian:~ $ 

(on the other hand, it takes just 3.3 ms, if you use it ONCE in your script… :-)

Upvotes: 5

Edouard Thiel
Edouard Thiel

Reputation: 6208

Here is a snippet that gives random integers between -30 and 30:

while true ; do echo $((RANDOM % 61 - 30)) ; done

More generally, to get random integers in range [a..b], try:

read a b
while true ; do echo $((RANDOM % (b-a+1) + a)) ; done

Upvotes: 2

Related Questions