Влад Иванов
Влад Иванов

Reputation: 27

How to find the Sum of digits recursively

I need to find the sum of digits in shell recursively. but I've a mistake: line 10: 5 + : syntax error: operand expected (error token is "+ ")

function countofnumbers
{
    if [ $1 -lt 10 ]
    then
        return $1
    else
        let z=$1/10
        let result=expr`$(($(( $1 % 10 )) + $(countofnumbers $z)))`
    fi
    return $result
}
z=15
echo $(countofnumbers $z)

Upvotes: 2

Views: 111

Answers (2)

jeremysprofile
jeremysprofile

Reputation: 11445

You were pretty close, nice job!

function countofnumbers {
    if [ $1 -lt 10 ]
    then
        echo $1
    else
        z=$(( $1 / 10 ))
        result=$(( $(( $1 % 10 )) + $(countofnumbers $z) ))
    fi
    echo $result
}

Here's the changes I made:

z=$(( $1 / 10 ))

Every time you do math in bash, wrap it in the arithmetic operators $(( )). While let works as well, you appear to be combining all 3 styles (expr, let, $(( ))) more or less at random. Your code will be more readable if you stick to one style.

result=$(( $(( $1 % 10 )) + $(count $z) ))

You just had too many things around this one. The arithmetic operators alone are enough. expr is an alternate form of the arithmetic operator, but we didn't need it here.

return $1
return $result

Bash doesn't do return like any other programming language. Return refers to the return code, which is a number 0-255, and is mainly used for expressing whether or not an error occurred. The results are captured just as you thought though, e.g.,

mynum=$(countofnumbers 12)
echo $mynum
> 3

Upvotes: 1

Ollin Boer Bohan
Ollin Boer Bohan

Reputation: 2401

First: bash is uniquely the wrong tool for this job.

But, anyway:

  • Bash functions don't have return in the way that you're trying to use it; the return statement sets the exit status. You should be using echo to produce output from the function.
  • Your big math expression is not well formed; expr is a command and should be inside the backticks, with a space after it, so that it gets run.
  • Stylistically, mixing let, expr, and $(()) is very messy, as is nesting all of them within a single line. Prefer using just $(()) for arithmetic expansion (it's the most standard and portable method) and prefer breaking up complex expressions into smaller ones.

With fixes:

function countofnumbers
{
    if [ "$1" -lt 10 ]
    then
        echo "$1"
    else
        z=$(($1 / 10))
        modded=$(($1 % 10))
        recursive_call=$(countofnumbers $z)
        result=$((modded + recursive_call))
    fi
    echo "$result"
}
z=15
countofnumbers "$z"

Upvotes: 0

Related Questions