BashShell数值运算

1. 简介

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

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

  • 外部命令:expr、bc、awk

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

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

2. 整数运算

整数运算 示例
加 ((i=i+1))、((i++))、((++i))、((i+=1))
let i=i+1、let i++、let ++i、let i+=1
i=$[i+1]、i=$[i++]、i=$[++i]、i=$[i+=1]
(++i 和 i++ 的区别同 C 语言)
i=$(expr $i + 1)
`i=$(echo $i+1
减 ((i=i-1))、((i--))、((--i))、((i-=1))
let i=i-1、let i--、 let --i、let i-=1
i=$[i-1]、i=$[i--]、i=$[--i]、i=$[i-=1]
(--i 和 i-- 的区别同 C 语言)
i=$(expr $i - 1)
`i=$(echo $i-1
乘 ((i=i*2))、((i*=2))
let i=i*2、let i*=2
i=$(expr $i \* 2)(乘号需要转义)
i=$[i*2]、i=$[i*=2]
`i=$(echo $i*2
除 ((i=i/2))、((i/=2))
let i=i/2、let i/=2
i=$[i/2]、i=$[i/=2]
i=$(expr $i / 2)
`i=$(echo $i/2
取模 ((i=i%2))、((i%=2))
let i=i%2、let 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<<1、let i<<=1、let i=i>>1、let i>>=1
i=$[i<<1]、i=$[i<<=1]、i=$[i>>1]、i=$[i>>=1]
(expr、bc 均不支持移位运算)
`i=(echo"(echo "i 1"
位取反 ((i=~i))
let i=~i
i=$[~i]
(expr、bc 均不支持位取反运算)
`i=(echo"(echo "i"
位与 ((i=i&2))、((i&=2))
let i=i&2、let i&=2
i=$[i&2]、i=$[i&=2]
(expr、bc 均不支持位与运算)
`i=(echo"(echo "i 2"
位或 `((i=i
位异或 ((i=i^2))、((i^=2))
let i=i^2、let i^=2
i=$[i^2]、i=$[i^=2]
(expr、bc 均不支持位或运算)
`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"
... ... ...