Bash算术问题

时间:2014-06-23 13:49:35

标签: bash

我有以下脚本,非常自我解释,但我遇到了超级奇怪的问题。

Multiply给我0

分区倍增

任何见解都会很棒!

谢谢, 奥斯汀

n1=$1
op=$2
n2=$3


case "$op" in

+)
        echo $(( $n1 + $n2 ))
        ;;
-)
        echo $(( $n1 - $n2 ))
        ;;

*)      echo $(( $n1 * $n2 ))
        ;;

/)      echo $(( $n1 / $n2 ))
        ;;
esac

4 个答案:

答案 0 :(得分:3)

@ gniourf_gniourf的评论是答案的90%,并完全解释为什么“分裂倍增”。另外10%是你需要在将*参数传递给此代码时引用它,否则它会全局展开,你的第三个参数将是一些文件名,在算术表达式中,它可能会评估到0。这就解释了为什么“Multiply给我0”。

你也可以通过设置noglob shell选项来防止globs扩展来解决这个问题。

比较

echo *
set -f
echo *

答案 1 :(得分:1)

考虑使用bc,因为bash不处理浮点数:

echo $((4/3))
1

使用bc

echo "4/3" | bc -l
1.33333333333333333333

答案 2 :(得分:1)

@kojiro's answer很好地解释了原始代码的问题(*必须引用以防止其解释为脚本中的默认case分支,并且在作为参数传递时阻止路径名扩展。)

@kojiro还指出,您可以在算术扩展表达式($((...)))中使用变量引用代替文字算术运算符。 警告:仅适用于$op - 前缀为$! - 不只是op(在{b}的算术上下文中$前缀是可选的。)

考虑到这一点,这是一个简化的解决方案,也可以执行操作员检查。 (为了使其完全健壮,还必须检查操作数)。

#!/bin/bash

n1=$1 op=$2 n2=$3

 # Allow 'x' to be passed as an alias for '*' (multiplication).
[[ "$op" == 'x' ]] && op='*'

 # Ensure that the operator is valid.
case $op in
    +|-|'*'|/) # note the quoted '*', needed to prevent interpretation as wildcard
        ;;
    *) # proper use of unquoted *: the everything-else branch
        echo "Error: Unexpected operator: $op" >&2
        exit 1 
esac

 # Perform the calculation. Note how the operator is provided via variable $op.
 # Note how the reference to variable `op` _must_ be `$`-prefixed in this case,
 # unlike the other two references.
echo $(( n1 $op n2 ))

答案 3 :(得分:0)

修正了它,但这是我必须解决的问题:

#!/bin/bash

n1=$1
op=$2
n2=$3

if [ "$op" == 'x' ]
then
echo $(( $n1 * $n2 ))
else
echo $(( $n1 $op $n2 ))
fi