# arith.tests   [plain text]

set +o posix
declare -i iv jv

iv=\$(( 3 + 5 * 32 ))
echo \$iv
iv=iv+3
echo \$iv
iv=2
jv=iv

let "jv *= 2"
echo \$jv
jv=\$(( \$jv << 2 ))
echo \$jv

let jv="\$jv / 2"
echo \$jv
jv="jv >> 2"
echo \$jv

iv=\$((iv+ \$jv))
echo \$iv
echo \$((iv -= jv))
echo \$iv
echo \$(( iv == jv ))
echo \$(( iv != \$jv ))
echo \$(( iv < jv ))
echo \$(( \$iv > \$jv ))
echo \$(( iv <= \$jv ))
echo \$(( \$iv >= jv ))

echo \$jv
echo \$(( ~\$jv ))
echo \$(( ~1 ))
echo \$(( ! 0 ))

echo \$(( jv % 2 ))
echo \$(( \$iv % 4 ))

echo \$(( iv <<= 16 ))
echo \$(( iv %= 33 ))

echo \$(( 33 & 55 ))
echo \$(( 33 | 17 ))

echo \$(( iv && \$jv ))
echo \$(( \$iv || jv ))

echo \$(( iv && 0 ))
echo \$(( iv & 0 ))
echo \$(( iv && 1 ))
echo \$(( iv & 1 ))

echo \$(( \$jv || 0 ))
echo \$(( jv | 0 ))
echo \$(( jv | 1 ))
echo \$(( \$jv || 1 ))

let 'iv *= jv'
echo \$iv
echo \$jv
let "jv += \$iv"
echo \$jv

echo \$(( jv /= iv ))
echo \$(( jv <<= 8 ))
echo \$(( jv >>= 4 ))

echo \$(( iv |= 4 ))
echo \$(( iv &= 4 ))

echo \$(( iv += (jv + 9)))
echo \$(( (iv + 4) % 7 ))

# unary plus, minus
echo \$(( +4 - 8 ))
echo \$(( -4 + 8 ))

# conditional expressions
echo \$(( 4<5 ? 1 : 32))
echo \$(( 4>5 ? 1 : 32))
echo \$(( 4>(2+3) ? 1 : 32))
echo \$(( 4<(2+3) ? 1 : 32))
echo \$(( (2+2)<(2+3) ? 1 : 32))
echo \$(( (2+2)>(2+3) ? 1 : 32))

# check that the unevaluated part of the ternary operator does not do
# evaluation or assignment
x=i+=2
y=j+=2
declare -i i=1 j=1
echo \$((1 ? 20 : (x+=2)))
echo \$i,\$x
echo \$((0 ? (y+=2) : 30))
echo \$j,\$y

x=i+=2
y=j+=2
declare -i i=1 j=1
echo \$((1 ? 20 : (x+=2)))
echo \$i,\$x
echo \$((0 ? (y+=2) : 30))
echo \$i,\$y

# check precedence of assignment vs. conditional operator
# should be an error
declare -i x=2
y=\$((1 ? 20 : x+=2))

# check precedence of assignment vs. conditional operator
declare -i x=2
echo \$((0 ? x+=2 : 20))

# associativity of assignment-operator operator
declare -i i=1 j=2 k=3
echo \$((i += j += k))
echo \$i,\$j,\$k

# octal, hex
echo \$(( 0x100 | 007 ))
echo \$(( 0xff ))
echo \$(( 16#ff ))
echo \$(( 16#FF/2 ))
echo \$(( 8#44 ))

echo \$(( 8 ^ 32 ))

# other bases
echo \$(( 16#a ))
echo \$(( 32#a ))
echo \$(( 56#a ))
echo \$(( 64#a ))

echo \$(( 16#A ))
echo \$(( 32#A ))
echo \$(( 56#A ))
echo \$(( 64#A ))

echo \$(( 64#@ ))
echo \$(( 64#_ ))

# weird bases
echo \$(( 3425#56 ))

# missing number after base
echo \$(( 2# ))

# these should generate errors
echo \$(( 7 = 43 ))
echo \$(( 2#44 ))
echo \$(( 44 / 0 ))
let 'jv += \$iv'
echo \$(( jv += \\$iv ))
let 'rv = 7 + (43 * 6'

# more errors
declare -i i
i=0#4
i=2#110#11

((echo abc; echo def;); echo ghi)

if (((4+4) + (4 + 7))); then
echo ok
fi

(())	# make sure the null expression works OK

a=(0 2 4 6)
echo \$(( a[1] + a[2] ))
echo \$(( (a[1] + a[2]) == a[3] ))
(( (a[1] + a[2]) == a[3] )) ; echo \$?

# test pushing and popping the expression stack
unset A
A="4 + "
echo \$(( ( 4 + A ) + 4 ))
A="3 + 5"
echo \$(( ( 4 + A ) + 4 ))

# badly-formed conditional expressions
echo \$(( 4 ? : \$A ))
echo \$(( 1 ? 20 ))
echo \$(( 4 ? 20 : ))

# precedence and short-circuit evaluation
B=9
echo \$B

echo \$(( 0 && B=42 ))
echo \$B

echo \$(( 1 || B=88 ))
echo \$B

echo \$(( 0 && (B=42) ))
echo \$B

echo \$(( (\${\$} - \$\$) && (B=42) ))
echo \$B

echo \$(( 1 || (B=88) ))
echo \$B

# until command with (( )) command
x=7

echo \$x
until (( x == 4 ))
do
echo \$x
x=4
done

echo \$x

# exponentiation
echo \$(( 2**15 - 1))
echo \$(( 2**(16-1)))
echo \$(( 2**16*2 ))
echo \$(( 2**31-1))
echo \$(( 2**0 ))

# {pre,post}-{inc,dec}rement and associated errors

x=4

echo \$x
echo \$(( x++ ))
echo \$x
echo \$(( x-- ))
echo \$x

echo \$(( --x ))
echo \$x

echo \$(( ++x ))
echo \$x

echo \$(( ++7 ))
echo \$(( 7-- ))

echo \$(( --x=7 ))
echo \$(( ++x=7 ))

echo \$(( x++=7 ))
echo \$(( x--=7 ))

echo \$x

echo \$(( +7 ))
echo \$(( -7 ))

echo \$(( ++7 ))
echo \$(( --7 ))

\${THIS_SH} ./arith1.sub
\${THIS_SH} ./arith2.sub

x=4
y=7

(( x=8 , y=12 ))

echo \$x \$y

# should be an error
(( x=9 y=41 ))

# These are errors
unset b
echo \$((a b))
((a b))

n=42
printf "%d\n" \$n
printf "%i\n" \$n
echo \$(( 8#\$(printf "%o\n" \$n) ))
printf "%u\n" \$n
echo \$(( 16#\$(printf "%x\n" \$n) ))
echo \$(( 16#\$(printf "%X\n" \$n) ))

# causes longjmp botches through bash-2.05b
a[b[c]d]=e