2010-08-03 75 views
3
fact() 
{ 
    if [ $1 -eq 1 ] 
    then 
     return 1 
    else 
     y=`expr $1 - 1` 
     fact $y 
     b=$(($1 * $?)) 
     return $b 
    fi 
} 
echo "enter" 
read n 
fact $n 
echo "$?" 

这是一个程序来查找一个数字的阶乘。输出是正确的最多5.输出6是给208,但正确的答案是720.什么导致这个错误?为什么我的bash函数返回错误的值?

+0

可能重复的阶乘[你如何在Bash脚本中找到数字的阶乘?](http://stackoverflow.com/questions/3394580/how-do-you-find-the-factorial-of-a-number-in- a-bash脚本) – 2010-08-03 13:39:59

回答

7

函数的返回值只能上升到255:

a() 
{ 
     return 255 
} 

a 
echo $? 

b() 
{ 
     return 256 
} 

b 
echo $? 

产地:

$ bash x.sh 
255 
0 

return就像exitexit只能采取值高达255(http://www.unix.org/whitepapers/shdiffs.html)。

一种替代方法是切换到迭代建议,如另一个答案中所述。 或者您可以使用回声和捕捉递归输出方式:

#!/bin/bash 

fact() 
{ 
    if [ $1 -eq 1 ] 
    then 
     echo 1 
    else 
     y=$(expr $1 - 1) 
     f=$(fact $y) 
     b=$(($1 * $f)) 
     echo $b 
    fi 
} 
echo "enter" 
read n 
fact $n 
1

有趣的是,在使用虚预期的程序工作,它只是无法使用bash。所以看起来这是一种抨击。

只需添加一行

#!/bin/dash 

在程序的顶部和它的作品!

+0

好奇心+1。不过,我预计它会再次突破一些稍大的数字。 – tripleee 2013-05-27 16:44:58

2

bourne shell不能在$存储吗? (退出代码)。限制为255。下面有一个替代的方式

n=0 
on=0 
fact=1 

echo -n "Enter number to find factorial : " 
read n 

on=$n 

while [ $n -ge 1 ] 
do 
    fact=`expr $fact \* $n` 
    n=`expr $n - 1` 
done 

echo "Factorial for $on is $fact" 
1

Bash脚本和Bash函数返回值都旨在被返回代码,并因此限制与它们能够返回的值。您不应该依赖于127以上的值(通常127以上的值 - 最多255)用于指示接收到的信号。

线条

fact $y 
b=$(($1 * $?)) 

希望使用$?fact返回代码,而这种代码不能被擦菜板则255

返回值的Bash的方式打印和解析或评估这个输出。

2

你所看到的是函数返回值在256处的环绕。720 mod 256208256 + 256 + 208 = 720)。

我的建议是,如果你必须使用shell功能,就是要做到:

#!/bin/bash 
fact() 
{ 
    if [ "$1" -eq "1" ] 
    then 
     echo 1 
     return 
    fi 
    y=`expr $1 - 1` 
    z=$(fact $y) 
    echo $(($1 * $z)) 
} 
echo "enter" 
read n 
echo "$(fact $n)" 

它使用标准输出返回值,而不是返回代码。

,或者甚至更好,使用权工具的作业:

pax> echo 'define f(x) {if (x>1){return x*f(x-1)};return 1} 
      f(6)' | bc 
720 
pax> echo 'define f(x) {if (x>1){return x*f(x-1)};return 1} 
      f(500)' | BC_LINE_LENGTH=99999 bc 
12201368259911100687
45373153881997605496447502203281863013616477148203584163378722078177 
20048078520515932928547790757193933060377296085908627042917454788242 
49127263443056701732707694610628023104526442188787894657547771498634 
94367781037644274033827365397471386477878495438489595537537990423241 
06127132698432774571554630997720278101456108118837370953101635632443 
29870295638966289116589747695720879269288712817800702651745077684107 
19624390394322536422605234945850129918571501248706961568141625359056 
69342381300885624924689156412677565448188650659384795177536089400574 
52389403357984763639449053130623237490664450488246650759467358620746 
37925184200459369692981022263971952597190945217823331756934581508552 
33282076282002340262690789834245171200620771464097945611612762914595 
12372299133401695523638509428855920187274337951730145863575708283557 
80158735432768888680120399882384702151467605445407663535984174430480 
12893831389688163948746965881750450692636533817505547812864000000000 
00000000000000000000000000000000000000000000000000000000000000000000 
00000000000000000000000000000000000000000000000 

我很愿意看到一个bash - 只计算解决方案:-) 500