Bash Arithmetic Operators Reference

All (( )) and let arithmetic operators with precedence and assignment forms.

Reference for Bash arithmetic expansion operators usable in $(( )), (( )) and let — covering arithmetic, bitwise, shift, comparison, logical, ternary and compound assignment, each ranked by precedence with a worked example.

Does Bash arithmetic support decimals?

No. Bash arithmetic is integer-only, so division truncates toward zero and there is no floating point. For decimal math, pipe the expression to bc with the -l flag or use awk, which both support real numbers.

Bash arithmetic operators

Bash evaluates integer math inside three constructs: arithmetic expansion $(( expr )) which substitutes the result, the arithmetic command (( expr )) which sets the exit status, and the let builtin. They share one operator set modelled on the C language: arithmetic, bitwise, shifts, comparison, logical, the ternary conditional and compound assignment. This page is a searchable, offline reference that also shows each operator’s precedence so you know when parentheses are required.

How it works

Inside an arithmetic context every token is interpreted numerically. Bare variable names expand to their values automatically, non-numeric strings become zero, and the whole expression yields an integer. Operators are applied in precedence order:

  • Highest binding: post/pre increment, unary sign and ~/!, then **.
  • Then the multiplicative * / %, additive + -, and shifts << >>.
  • Then relational < <= > >=, equality == !=.
  • Then the bitwise trio in order &, ^, | — note these bind looser than the comparisons, a common source of bugs.
  • Then logical && and ||, the ternary ?:, and finally assignment and the comma operator.

Comparison and logical operators return 1 for true and 0 for false, which is why (( x > 0 )) works as a condition: a non-zero result is a success exit status.

Tips and examples

Use the arithmetic command directly as a loop condition:

for (( i = 0; i < 5; i++ )); do
  echo "$i squared is $(( i ** 2 ))"
done

Compound assignment keeps counters terse:

total=0
(( total += 25 ))   # total is now 25
(( total <<= 1 ))   # bit-shift left → 50

The ternary operator picks a value inline without an if:

max=$(( a > b ? a : b ))

Remember everything is integer math: $(( 7 / 2 )) is 3, not 3.5. For fractional results, reach for bc -l or awk instead.