将浮点数与 shell 脚本中的 if-else 语句进行比较

将浮点数与 shell 脚本中的 if-else 语句进行比较

因此,我一直在编写这个脚本来获取成绩输入,然后它会根据每个部分的权重来计算它们。最后,它将根据计算出的成绩输出字母成绩。我的代码在 if-else 语句之前都很好,在 if-else 语句之前我将开始在每个 if-else 语句的条件下收到非法数字的错误。

#!/bin/sh
#Calculate weighted grade and output grade letter

echo "What is your total Lab/Assignments grade?"
read labGrade
echo "What is your Midterm grade?"
read midtermGrade
echo "What is your total Quizzes grade?"
read quizGrade
echo "What is your Final Exam grade?"
read finalGrade

weightedLab=`echo "0.25*$labGrade" | bc`
weightedMidterm=`echo "0.30*$midtermGrade" | bc`
weightedQuiz=`echo "0.15*$quizGrade" | bc`
weightedFinal=`echo "0.30*$finalGrade" | bc`

totalGrade=`echo "$weightedLab + $weightedMidterm + $weightedQuiz + $weightedFinal" | bc`

if [ $totalGrade -ge 90.00 ]
then
        echo "Your total grade is an A+!"
elif [ $totalGrade -ge 85.00 -a $totalGrade -le 89.00 ]
then
        echo "Your total grade is an A!"
elif [ $totalGrade -ge 80.00 -a $totalGrade -le 84.00 ]
then
       echo "Your total grade is an A-!"
elif [ $totalGrade -ge 76.00 -a $totalGrade -le 79.00 ]
then
        echo "Your total grade is a B+"
elif [ $totalGrade -ge 72.00 -a $totalGrade -le 75.00 ]
then
        echo "Your total grade is a B"
elif [ $totalGrade -ge 68.00 -a $totalGrade -le 71.00 ]
then
        echo "Your total grade is a B-"
elif [ $totalGrade -ge 64.00 -a $totalGrade -le 67.00 ]
then
        echo "Your total grade is a C+"
elif [ $totalGrade -ge 60.00 -a $totalGrade -le 63.00 ]
then
        echo "Your total grade is a C"
elif [ $totalGrade -ge 56.00 -a $totalGrade -le 59.00 ]
then
        echo "Your total grade is a C-"
elif [ $totalGrade -ge 50.00 -a $totalGrade -le 55.00 ]
then
        echo "Your total grade is a D"
else
        echo "Your total grade is an F"
fi
What is your total Lab/Assignments grade?
100
What is your Midterm grade?
100
What is your total Quizzes grade?
100
What is your Final Exam grade?
90
./A2.sh: 20: [: Illegal number: 97.00
./A2.sh: 23: [: Illegal number: 97.00
./A2.sh: 26: [: Illegal number: 97.00
./A2.sh: 29: [: Illegal number: 97.00
./A2.sh: 32: [: Illegal number: 97.00
./A2.sh: 35: [: Illegal number: 97.00
./A2.sh: 38: [: Illegal number: 97.00
./A2.sh: 41: [: Illegal number: 97.00
./A2.sh: 44: [: Illegal number: 97.00
./A2.sh: 47: [: Illegal number: 97.00
Your total grade is an F

如何更改代码以正确比较这些值?

答案1

Bash 不进行浮点运算。

但是由于您不需要任意比例,因此您只需将数字放大一百进行计算,这样您就只剩下整数,例如

lab=100 midterm=70 quiz=90 exam=80
total=$((25*lab + 30*midterm + 15*quiz + 30*exam))
if (( total >= 8000 )); then
    echo "you scored at least 80! (actually $(( total / 100 )))"
fi

或者您可以使用其他可以处理浮点数的工具,请参阅:
如何在 bash 或其他语言/框架中进行整数和浮点计算?

答案2

首先:bash只能处理整数。因此,您还需要使用外部进行浮点比较。

一种简单的方法是使用,它在 FALSE 语句上bc输出,而在 TRUE 语句上,比较运算符是, , , , , 和。它们的工作方式正如您所了解的那样。01<<=>>===!=

 echo '1 > 2' | bc -l
 0
 echo '1 <= 2' | bc -l
 1

因此将你的测试更改为

 [ $(echo "$totalGrade >= 90.00" | bc -l) -eq 1 ]

等等。

提示1

elif [ $totalGrade -ge 80.00 -a $totalGrade -le 84.00 ]

在此表达式中,-a $totalGrade -le 84.00是多余的,因为 IF 循环的计算顺序与脚本中的顺序相同,因此$totalGrade -le 84.00一旦为 FALSE,就已被处理$totalGrade -ge 85.00

提示2如果成绩是 84.5 会怎样?您的评估忽略了这些价值观。

相关内容