2022-10-09 14:50:24 -06:00
|
|
|
# Working with numbers in bash
|
|
|
|
Bash interprets everything by default as a string, however it can also work with
|
|
|
|
numbers, just be careful with your conditional operators
|
|
|
|
|
|
|
|
## Storing numbers
|
|
|
|
`declare` and `local` both can make integer variables with the `-i` flag
|
|
|
|
|
|
|
|
```bash
|
|
|
|
declare -i a=2
|
|
|
|
|
|
|
|
f () { local -i a=3 ;}
|
|
|
|
```
|
|
|
|
|
|
|
|
Variables can be manipulated in double parenthesis, very similar to c/python.
|
|
|
|
Use `$(())` to return the value instead. Edges and centers seem whitespace
|
|
|
|
insensitive. No need to `$` in front of variables inside `(())`
|
|
|
|
|
|
|
|
Work as expected: `+ - * %`
|
|
|
|
Exponent: `**`
|
|
|
|
Floored division: `/`
|
|
|
|
|
|
|
|
```bash
|
|
|
|
declare -i a=2 b=3 # Multiple on the same line are fine
|
|
|
|
|
|
|
|
(( a++ )) # a == 3
|
|
|
|
(( a+=b )) # a == 6
|
|
|
|
(( a = 2 )) # a == 2
|
|
|
|
((a=4+b)) # a == 7
|
|
|
|
(( a = 4 + b )) # Spacing is optional, same as above
|
|
|
|
|
|
|
|
declare -i c=$((a**b + 4)) # c == 7**3 + 4 == 347
|
2022-10-15 14:15:39 -06:00
|
|
|
|
|
|
|
declare -ia arr=(0 1 2 3)
|
|
|
|
(( arr[a] = 3 )) # Array indexing also no longer needs $
|
|
|
|
(( arr[100] = 3 )) # Array is acc an integer hashmap, so over-indexing works
|
2022-10-09 14:50:24 -06:00
|
|
|
```
|
|
|
|
|
|
|
|
## Using numbers
|
|
|
|
Conditionals are different for numbers in bash. Mapping c to bash:
|
|
|
|
|
|
|
|
```
|
|
|
|
C | Bash
|
|
|
|
----|-----
|
|
|
|
== | -eq
|
|
|
|
!= | -ne
|
|
|
|
> | -gt
|
|
|
|
< | -lt
|
|
|
|
>= | -ge
|
|
|
|
<= | -le
|
|
|
|
```
|
|
|
|
|
|
|
|
```bash
|
|
|
|
declare -i a=3 b=2
|
|
|
|
|
|
|
|
if [[ $((a**b)) -ge 1000 ]]; then
|
|
|
|
echo "Exponentiation with ${a}^${b} is pretty big"
|
|
|
|
elif [[ $a -lt $b ]]; then
|
|
|
|
echo "$a is smaller than $b"
|
|
|
|
else
|
|
|
|
echo "$a isn't smaller than $b"
|
|
|
|
fi
|
|
|
|
|
|
|
|
echo "You rolled a: $(( RANDOM % 6 + 1 )) on a 6 sided dice"
|
|
|
|
```
|
|
|
|
|
|
|
|
## Floats
|
|
|
|
Bash has no support for floats, don't even try. If you need floats, use awk,
|
|
|
|
which has full support. To still sort of use rational numbers in bash, store a
|
|
|
|
numerator and denominator, then pass both to awk when you need the float
|
|
|
|
|
|
|
|
```bash
|
|
|
|
declare -i num_1=4 denom_1=9
|
|
|
|
declare -i num_2=2 denom_2=9
|
|
|
|
|
|
|
|
(( num_1 += num_2 ))
|
|
|
|
|
|
|
|
awk -v n1=$num_1 -v d1=$denom_1 -v n2=$num_2 -v d2=$denom_2 \
|
|
|
|
'BEGIN { printf "%.2f\n", n1/d1 + n2/d2 }'
|
|
|
|
```
|
|
|
|
|
|
|
|
Bash has floored division `/` and remainders `%`, though the awk approach is
|
|
|
|
easier. Note awk's syntax is identical to c, so it uses `^` for exponentiation
|
|
|
|
and the standard `==`, `<=`... for comparison
|