Question

I am just trying to Convert secs back to hours n minutes for a day. However am hitting an error in the Minute Equation! its not evaluating the braces in the order! how can we evalvate math equations like the one I have below.

I want to divide the total_secs by 3600 and then multiply the result with 60 then Again find the modulus of the result with 60.

Here s my attempt

#!/bin/ksh  
set -x  
total_secs=3685;  
hour=$(( (total_secs % 3600) ));  
minute=$(( (((total_secs / 3600) * 60) % 60) ));  
seconds=$(( (((total_secs / 3600) * (60) * (60)) % 60) ));  
echo ""$hour":"$minute":"$seconds""  

Thanks In advance

Was it helpful?

Solution

The ordering of operations wasn't what was causing the problem. According to this reference, the Korn shell has the same precedence and associativity as the C programming language, so multiplication, division and remainder happen from left to right. The correct maths would be:

#!/bin/ksh

total_secs=3685
hour=$(( total_secs / 3600 ))
minute=$(( total_secs / 60 % 60  )) # equivalent to (total_secs / 60) % 60
seconds=$(( total_secs % 60 ))
echo "$hour:$minute:$seconds"
# output 1:1:25

If you want to format the output, perhaps you could use printf

printf "%02d:%02d:%02d\n" $hour $minute $seconds
# output 01:01:25

edit: operator precedence

Basic arithmetic operations are carried out in the following order:

  1. * / %
  2. + -

Multiple operations of the same precedence will be evaluated from left to right as they appear in the expression.

$(( ((x*y) / z) + n ))

is equivalent to either of the following:

$(( x * y / z + n ))
$(( n + x * y / z ))

because in both cases, the * is the highest precedence and nearest to the left of the expression. Second will be the / and finally the +.

There is no harm in inserting additional ( ) to make your intentions clear but remember that the whole expression must be enclosed within $(( )).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top