1
#!/bin/bash
echo "Enter a number: "
read number
factorial=1
function FactorialMethod()
{
num=$1
while [[ $num -ge 1 ]]
do
    factorial=$(( $factorial*$num ))
    num=$(($num - 1))
done
return $factorial
}
FactorialMethod $number
result=$?
echo "Factorial of "$number" is "$result
  • When I run this code and I input numbers from 0 to 5 I'm getting correct answers. However when I input numbers from 6 and above I'm getting wrong answers... What is wrong with my code?

  • I'm new to StackOverflow so I'm sorry if this was a repeated question and thank you for your help :)

POTATO
  • 11
  • 1
  • "However when I input numbers from 6 and above I'm getting wrong answers" --> often useful to post the input and wrong answers than only describe them. – chux - Reinstate Monica Apr 01 '22 at 14:06
  • `result=$?` is the return code, not the value of factorial – 0stone0 Apr 01 '22 at 14:12
  • @0stone0 What do you mean? – POTATO Apr 01 '22 at 14:17
  • 4
    Please read the first line of the accepted answer in the marked question: "Although Bash has a return statement, the only thing you can specify with it is the function's own exit status (a value between 0 and 255, 0 meaning "success"). So return is not what you want." – 0stone0 Apr 01 '22 at 14:17
  • `return` in bash is not designed for returning a value it's designed specially for status codes and only values between 0 and 255 are accepted. – Ivan Apr 01 '22 at 14:26
  • BTW, `function funcname() {` is the _worst_ of the function declaration syntax options bash provides: It merges the ksh `function funcname {` and the POSIX-compliant `funcname() {` while being incompatible with **both** ksh and POSIX. See https://wiki.bash-hackers.org/scripting/obsolete – Charles Duffy Apr 01 '22 at 15:18

2 Answers2

1

Posting as a community answer since this is an obvious duplicate


Return value in a Bash function

Although Bash has a return statement, the only thing you can specify with it is the function's own exit status (a value between 0 and 255, 0 meaning "success").

So return is not what you want.


The reason why it works for 5, but not for 6 is because 5! is smaller then 255. but 6! is 720


So replace the following

# Wrong
return $factorial

# Correct
echo $factorial

And

# Wrong
FactorialMethod $number
result=$?

# Correct
result=$(FactorialMethod $number)

Final code:

#!/bin/bash

echo "Enter a number: "
read number
factorial=1

function FactorialMethod() {
    num=$1
    while [[ $num -ge 1 ]]
    do
        factorial=$(( $factorial*$num ))
        num=$(($num - 1))
    done
    echo $factorial
}

result=$(FactorialMethod $number)
echo "Factorial of "$number" is "$result
0stone0
  • 21,605
  • 3
  • 29
  • 49
0

As described at this article,

Bash functions, unlike functions in most programming languages do not allow you to return a value to the caller.

So,

The simplest way to return a value from a bash function is to just set a global variable to the result. Since all variables in bash are global by default

In this case, you could simply call the method, and then check the value of the (global) variable factorial:

#!/bin/bash
echo "Enter a number: "
read number
factorial=1 # here the global variable is defined
function FactorialMethod()
{
  num=$1
  while [[ $num -ge 1 ]]
  do
      factorial=$(( $factorial*$num )) # this line will update the global variable
      num=$(($num - 1))
  done
}
FactorialMethod $number # calls the method so that the value of 'factorial' is updated properly
echo "Factorial of "$number" is "$factorial # 'factorial' variable will have the correct value
  • I'd consider `while (( num >= 1 ))`; if you're going to depend on bash extensions might as well use the good ones. Similarly, you can use `factorial=$(( factorial * num ))`, or `(( factorial *= num ))`; `(( --num ))`, `(( num -= 1 ))`, etc. – Charles Duffy Apr 01 '22 at 15:19
  • 1
    BTW, if a high-rep user posted their answer community wiki (meaning they're disclaiming any ownership over and reputation from that answer, typically because that answer is in some way against the site's rules: in this case, because the question is a duplicate), that's a hint that the question maybe _shouldn't_ be answered. (And because community-wiki answers disclaim ownership, one can always add to them without needing to worry about the original author's ownership/intent/etc). – Charles Duffy Apr 01 '22 at 15:24
  • Got it, @CharlesDuffy. Thank you very much for adding some more information regarding the code itself and for the hint about the duplicate question. I hadn't seen that the page had been set as duplicate. So, I'm sorry for replying something even though it's a duplicate. Once again, thank you! – Marcos Parreiras Apr 01 '22 at 15:36