BashShell数值运算

1. 简介

Bash Shell 本身一些内置命令可以执行简单的整数运算,但复杂一些的运算(比如浮点数运算)需要通过一些外部命令来实现,Bash Shell 数学运算符只支持整数运算。

  • 内置命令:(( ))let$[ ](方括号并不是所有的 Shell 都支持)

  • 外部命令:exprbcawk

从运行效率来看,Bash Shell 内置命令的执行效率要高于外部命令,(( )) 执行效率最高,其次是 let,外部命令执行效率相对来说较低。

【注】expr 运算在运算符和变量之间需要用空格分开,如果进行乘法运算,还需要对乘号进行转义 \*,否则 Bash Shell 会把乘号解释为通配符而报错。Bash Shell 内置命令和 expr 都不能进行浮点运算,但 bcawk 可以。

2. 整数运算

整数运算 示例
((i=i+1))((i++))((++i))((i+=1))
let i=i+1let i++let ++ilet i+=1
i=$[i+1]i=$[i++]i=$[++i]i=$[i+=1]
++ii++ 的区别同 C 语言)
i=$(expr $i + 1)
`i=$(echo $i+1
((i=i-1))((i--))((--i))((i-=1))
let i=i-1let i-- let --ilet i-=1
i=$[i-1]i=$[i--]i=$[--i]i=$[i-=1]
--ii-- 的区别同 C 语言)
i=$(expr $i - 1)
`i=$(echo $i-1
((i=i*2))((i*=2))
let i=i*2let i*=2
i=$(expr $i \* 2)(乘号需要转义)
i=$[i*2]i=$[i*=2]
`i=$(echo $i*2
((i=i/2))((i/=2))
let i=i/2let i/=2
i=$[i/2]i=$[i/=2]
i=$(expr $i / 2)
`i=$(echo $i/2
取模 ((i=i%2))((i%=2))
let i=i%2let i%=2
i=$[i%2]i=$[i%=2]
i=$(expr $i % 2)
`i=$(echo $i%2
求幂 ((i=i**2))
let i=i**2
i=$[i**2]
`i=$(echo $i^2
移位 ((i=i<<1))((i<<=1))((i=i>>1))((i>>=1))
let i=i<<1let i<<=1let i=i>>1let i>>=1
i=$[i<<1]i=$[i<<=1]i=$[i>>1]i=$[i>>=1]
exprbc 均不支持移位运算)
`i=(echo"(echo "i 1"
位取反 ((i=~i))
let i=~i
i=$[~i]
exprbc 均不支持位取反运算)
`i=(echo"(echo "i"
位与 ((i=i&2))((i&=2))
let i=i&2let i&=2
i=$[i&2]i=$[i&=2]
exprbc 均不支持位与运算)
`i=(echo"(echo "i 2"
位或 `((i=i
位异或 ((i=i^2))((i^=2))
let i=i^2let i^=2
i=$[i^2]i=$[i^=2]
exprbc 均不支持位或运算)
`i=(echo"(echo "i 2"

3. 浮点运算

【注】bc 在进行浮点运算时需要用 scale 指定小数位数,否则默认为 0,即结果只保留整数;或者不使用 scale 指定小数位数而使用 bc -l,默认小数精度为 20 位。awk 通过 printf 的格式控制来控制小数位数。

外部命令 示例
bc `echo "scale = 5; 0.5+0.5"
awk `echo "0.5 0.5"

4. 其他运算

  • 函数运算

bc 命令提供了数学函数库(需指定 -l 选项,该选项默认小数精度为 20 位),包含了一些基本的数学函数(以下三角函数均采用弧度值):

函数 命令 示例
sin(x) s(x) `echo "s($x)"
cos(x) c(x) `echo "c($x)"
arctan(x) a(x) `echo "a($x)"
ln(x) l(x) `echo "l($x)"
exp(x) e(x) `echo "e($x)"
开方 sqrt(x) `echo "sqrt($x)"
... ... ...

awk 命令同样提供了一些基本数学函数:

函数 命令 示例
sin(x) sin(x) `echo "$i"
cos(x) cos(x) `echo "$i"
arctan(x) atan2(y,x) `echo "$i $j"
ln(x) log(x) `echo "$i"
exp(x) exp(x) `echo "$i"
开方 sqrt(x) `echo "$i"
... ... ...