zoukankan      html  css  js  c++  java
  • Shell之数学计算

    本博客已经迁往http://www.kemaswill.com/, 博客园这边也会继续更新, 欢迎关注~

    数学计算是Shell中比较常用的一种操作,  但是因为shell中所有的变量都默认为字符串, 这就使得在shell中进行数学计算比较复杂, 以下直觉上貌似正确的方法是不对的:

    #第一种错误方法
    $ var=1+1
    #第二种错误方法
    $ var=1
    $ var=$var+1

    以上两种方法的输出结果都是1+1 , 而不是我们期望的2 .

    在shell中进行数学计算可以通过以下方法来进行:

    1. declare

    我们可以声明一个变量的类型, 比如声明变量n为整数declare -i n

    $ n=6/3
    $ echo $n
    6/3
    $ declare -i n
    $ n=6/3
    $ echo $n
    2

    2. expr

    可以使用expr命令, 注意其对空格比较敏感, 需要在+号附近都有空格

    $ z=5
    $ z=`expr $z+1`   ---- Need spaces around + sign.
    $ echo $z
    5+1
    $ z=`expr $z + 1`
    $ echo $z
    6

    3. let

    let也是对空格敏感的, 不过与expr相反, 其+号附近不能有空格(略难记啊...:(), let语句中还可以省略$符号

    $ let z=5
    $ echo $z
    5
    $ let z=$z+1
    $ echo $z
    6
    $ let z=$z + 1     # --- Spaces around + sign are bad with let
    -bash: let: +: syntax error: operand expected (error token is "+")
    
    $let z=z+1         # --- look Mom, no $ to read a variable.
    $echo $z
    7

    let的另一种形式是用双括号把数学计算的语句包围起来, 而且对空格比较宽容, 在+号附近有无空格都可以

    $ ((e=5))
    $ echo $e
    5
    $ (( e = e + 3 ))
    $ echo $e
    8
    $ (( e=e+4 ))  # -- spaces or no spaces, it doesn't matter
    $ echo $e
    12

    4. bc

    let不支持浮点数操作, 这时候需要用到bc

    $let r=3.5
    -bash: let: r=3.5: syntax error in expression (error token is ".5")
    $(( r = 3.5 ))
    -bash: ((: r = 3.5 : syntax error in expression (error token is ".5 ")

    bc既可以以交互的方式执行, 也可以作为shell的一个命令.

    交互方式:

    $ bc
    bc 1.06
    Copyright 1991-1994, 1997, 1998, 2000 Free Software Foundation, Inc.
    This is free software with ABSOLUTELY NO WARRANTY.
    For details type `warranty'.
    3 + 2
    5
    obase=2
    12
    1100
    <cntrl-d>

    作为shell的一个命令:

    $r=3.5
    $s=`echo "$r + 2.2" | bc`
    $echo $s
    5.7
    
    $ z = `echo $z + 1 | bc`
    -bash: z: command not found
                    # =号附近不能有空格, 这是shell的语法限制的, 不是bc
    
    $ z=`echo "$z + 1" | bc`
    $ echo $z
    8
    $ z=`echo "$z+1" | bc`  #bc中对空格不敏感
    $ echo $z
    9

    5. 其他

    网上有人总结了一个非常全的各种shell中数学计算的方法[2]:

    $ echo $((20.0/7))
    $ zcalc
    $ bc <<< 20+5/2
    $ bc <<< 'scale=4;20+5/2'
    $ expr 20 + 5
    $ calc 2 + 4
    $ node -pe 20+5/2  # Uses the power of JavaScript, e.g. : node -pe 20+5/Math.PI
    $ echo 20 5 2 / + p | dc 
    $ echo 4 k 20 5 2 / + p | dc 
    $ perl -E "say 20+5/2"
    $ python -c "print 20+5/2"
    $ python -c "print 20+5/2.0"
    $ clisp -x "(+ 2 2)"
    $ lua -e "print(20+5/2)"
    $ php -r 'echo 20+5/2;'
    $ ruby -e 'p 20+5/2'
    $ ruby -e 'p 20+5/2.0'
    $ guile -c '(display (+ 20 (/ 5 2)))'
    $ guile -c '(display (+ 20 (/ 5 2.0)))'
    $ slsh -e 'printf("%f",20+5/2)'
    $ slsh -e 'printf("%f",20+5/2.0)'
    $ tclsh <<< 'puts [expr 20+5/2]'
    $ tclsh <<< 'puts [expr 20+5/2.0]'
    $ sqlite3 <<< 'select 20+5/2;'
    $ sqlite3 <<< 'select 20+5/2.0;'
    $ echo 'select 1 + 1;' | sqlite3 
    $ psql -tAc 'select 1+1
    $ R -q -e 'print(sd(rnorm(1000)))'
    $ r -e 'cat(pi^2, "
    ")'
    $ r -e 'print(sum(1:100))'
    $ smjs
    $ jspl

    参考文献:

    [1]. Math in Shell Scripts

    [2]. How to do integer & float calculations, in bash or other languages/frameworks?

    [3]. Shell中数学计算总结

  • 相关阅读:
    面向对象方法的重载(overloading)和覆盖(overriding)。
    注意:在对象变量中存放的是引用(地址);在简单变量中存放的是数值。
    类方法中的一类特殊方法:构造方法。
    在用面向对象思想开发的过程中,可以复用对象就进行复用,如无法进行复用则开发新的对象。
    对于对象的要求:高内聚、低耦合,这样容易拼装成为一个系统。
    为什么要使用面向对象:
    什么是对象:EVERYTHING IS OBJECT(万物皆对象)
    Java如何在指定端口创建套接字?
    Java如何查找系统的代理设置?
    Java如何检查端口是否被使用?
  • 原文地址:https://www.cnblogs.com/kemaswill/p/3535200.html
Copyright © 2011-2022 走看看