Syntax error in subtraction in Bash

I am sharing a code snippet.

for (( i=0; i<=$(( $count -1 )); i++ ))
do

	first=${barr2[$i]}
	search=${barr1[$i]}
        echo $first
	echo "loop begins"
	for (( j=0; j<=5000; j++ ))
	do
		if [[ ${harr1[j]} == $search ]]; then
			echo $j
			break;
		fi

	done
	second=${harr2[$j]}	
	echo $second
	
	diff=$((second-first))
	echo "diff" 
	echo $diff
done 

I am getting a syntax error in line of subtraction that says something like:
syntax error: invalid arithmetic operator (error token is ".0985146")

This is the line that gives error.

	diff=$((second-first))

Appreciate your help.

I am assuming you are using bash or perhaps a POSIX shell like dash.
Your error is telling you that it is not possible to do such a task as these shells have INTEGER arithmetic only.

If you need floating/fixed point arithmetic then you will have to do workarounds using, bc, dc, python, perl, awk or any other methods that are capable of such mechanisms.

(Just an observation, you have both, ${barr1[$i]} and also ${harr1[j]} are these correct?)

EDIT:
Note the second one should have ${harr1[$j]}

An example longhand using INTEGER arithmetic and FIXED point, OSX 10.14.6, default bash terminal:

Last login: Mon Oct 21 18:25:40 on ttys000
AMIGA:amiga~> x=.098765
AMIGA:amiga~> y=10.3
AMIGA:amiga~> x=$( printf "%.f" ${x}e+12 )
AMIGA:amiga~> y=$( printf "%.f" ${y}e+12 )
AMIGA:amiga~> printf "%.12f\n" $(( y - x ))e-12
10.201235000000
AMIGA:amiga~> _
3 Likes

Nice wisecracker. This method would rap up into a fun little bash sum function:

function sum
{
   local word exp var

   [[ "$1" = *= ]] && var="-v ${1%=}" && shift

   for word in "$@"
   do
       case "$word" in
          [0-9.]*|-[0-9.]*|+|-)
              printf -v ans "%.f" "${word}e+12" 2>/dev/null || ans=$word
              exp="$exp $ans" ;;
          *) echo "sum: $word operator not supported" >&2 ; exit 1 ;;
       esac
   done
   printf $var "%.8f\n" $(( $exp ))e-12
}

sum val= 3.58047 - .68 + .858 + -1.2
echo $val
2 Likes
Moderator comments were removed during original forum migration.

Try:
diff=$(( $second - $first ))

EDIT:
I just necro'd a 7 month old thread thanks to autobumping.

2 Likes

Thanks!

That is what we want members to do.

When we reply to older threads, member will be notified by email and hopefully they will visit the new site and join us.

The idea of "necro'ing old threads" does not apply in a migrated forum.

Keep up the great work, @sea and reply to more old threads, like @kduffin also enjoys doing!

1 Like

Now the mummy is alive :wink:

If the context enforces a number as in $(( )) or (( )) then variables can be used without the $ prefix.
The $ enables additional manipulation like

diff=$(( 10#$second - 10#$first ))
diff=$(( ${second%.*} - ${first%.*} ))

where the 2nd example could even fix the problem. (It strips off a trailing .* in string context then the result converts back to a number.)

BTW

Yes, because a normal array enforces a number as index.

3 Likes

Moreover, the index in an indexed array is interpreted as an arithmetic expression that must evaluate to an integer.

3 Likes