⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mathc.html

📁 BASH Shell 编程 经典教程 《高级SHELL脚本编程》中文版
💻 HTML
📖 第 1 页 / 共 2 页
字号:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><HTML><HEAD><TITLE>数学计算命令</TITLE><METANAME="GENERATOR"CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINKREL="HOME"TITLE="高级Bash脚本编程指南"HREF="index.html"><LINKREL="UP"TITLE="外部过滤器, 程序和命令"HREF="external.html"><LINKREL="PREVIOUS"TITLE="终端控制命令"HREF="terminalccmds.html"><LINKREL="NEXT"TITLE="混杂命令"HREF="extmisc.html"></HEAD><BODYCLASS="SECT1"BGCOLOR="#FFFFFF"TEXT="#000000"LINK="#0000FF"VLINK="#840084"ALINK="#0000FF"><DIVCLASS="NAVHEADER"><TABLESUMMARY="Header navigation table"WIDTH="100%"BORDER="0"CELLPADDING="0"CELLSPACING="0"><TR><THCOLSPAN="3"ALIGN="center">高级Bash脚本编程指南: 一本深入学习shell脚本艺术的书籍</TH></TR><TR><TDWIDTH="10%"ALIGN="left"VALIGN="bottom"><AHREF="terminalccmds.html"ACCESSKEY="P">前一页</A></TD><TDWIDTH="80%"ALIGN="center"VALIGN="bottom">12. 外部过滤器, 程序和命令</TD><TDWIDTH="10%"ALIGN="right"VALIGN="bottom"><AHREF="extmisc.html"ACCESSKEY="N">下一页</A></TD></TR></TABLE><HRALIGN="LEFT"WIDTH="100%"></DIV><DIVCLASS="SECT1"><H1CLASS="SECT1"><ANAME="MATHC">12.8. 数学计算命令</A></H1><P></P><DIVCLASS="VARIABLELIST"><P><B><ANAME="MATHCOMMANDLISTING1"></A><SPANCLASS="QUOTE">"操作数字"</SPAN></B></P><DL><DT><BCLASS="COMMAND">factor</B></DT><DD><P>将一个正数分解为多个素数. </P><P>	      <TABLEBORDER="1"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="SCREEN"><SAMPCLASS="PROMPT">bash$ </SAMP><KBDCLASS="USERINPUT">factor 27417</KBD><SAMPCLASS="COMPUTEROUTPUT">27417: 3 13 19 37</SAMP>	      </PRE></FONT></TD></TR></TABLE>	    </P></DD><DT><ANAME="BCREF"></A><BCLASS="COMMAND">bc</B></DT><DD><P>Bash不能处理浮点运算, 并且缺乏特定的一些操作, 			  这些操作都是一些重要的计算功能. 幸运的是, 	      <BCLASS="COMMAND">bc</B>可以解决这个问题. </P><P><BCLASS="COMMAND">bc</B>不仅仅是个多功能灵活的精确计算工具, 	      且它还提供许多编程语言才具备的一些方便功能. </P><P><BCLASS="COMMAND">bc</B>比较类似于C语言的语法. </P><P>因为它是一个完整的UNIX工具, 所以它可以用在<AHREF="special-chars.html#PIPEREF">pipe</A>中, 	       <BCLASS="COMMAND">bc</B>在脚本中也是很常用的. </P><P>这里有一个简单的使用<BCLASS="COMMAND">bc</B>命令的模版, 可以用来计算脚本中的变量. 	      这个模版经常用于<AHREF="commandsub.html#COMMANDSUBREF">命令替换</A>中. </P><P>              <TABLEBORDER="1"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="SCREEN">	      <KBDCLASS="USERINPUT">variable=$(echo "OPTIONS; OPERATIONS" | bc)</KBD>	      </PRE></FONT></TD></TR></TABLE>	      </P><DIVCLASS="EXAMPLE"><HR><ANAME="MONTHLYPMT"></A><P><B>例子 12-42. 按月偿还贷款</B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="PROGRAMLISTING">  1&nbsp;#!/bin/bash  2&nbsp;# monthlypmt.sh: 计算按月偿还贷款的数量.   3&nbsp;  4&nbsp;  5&nbsp;#  这份代码是一份修改版本, 原始版本在"mcalc"(贷款计算)包中,   6&nbsp;#+ 这个包的作者是Jeff Schmidt和Mendel Cooper(本书作者).   7&nbsp;#   http://www.ibiblio.org/pub/Linux/apps/financial/mcalc-1.6.tar.gz  [15k]  8&nbsp;  9&nbsp;echo 10&nbsp;echo "Given the principal, interest rate, and term of a mortgage," 11&nbsp;echo "calculate the monthly payment." 12&nbsp; 13&nbsp;bottom=1.0 14&nbsp; 15&nbsp;echo 16&nbsp;echo -n "Enter principal (no commas) " 17&nbsp;read principal 18&nbsp;echo -n "Enter interest rate (percent) "  # 如果是12%, 那就键入"12", 而不是".12".  19&nbsp;read interest_r 20&nbsp;echo -n "Enter term (months) " 21&nbsp;read term 22&nbsp; 23&nbsp; 24&nbsp; interest_r=$(echo "scale=9; $interest_r/100.0" | bc) # 转换成小数.  25&nbsp;                 # "scale"指定了有效数字的个数. 26&nbsp;   27&nbsp; 28&nbsp; interest_rate=$(echo "scale=9; $interest_r/12 + 1.0" | bc) 29&nbsp;  30&nbsp; 31&nbsp; top=$(echo "scale=9; $principal*$interest_rate^$term" | bc) 32&nbsp; 33&nbsp; echo; echo "Please be patient. This may take a while." 34&nbsp; 35&nbsp; let "months = $term - 1" 36&nbsp;# ====================================================================  37&nbsp; for ((x=$months; x &#62; 0; x--)) 38&nbsp; do 39&nbsp;   bot=$(echo "scale=9; $interest_rate^$x" | bc) 40&nbsp;   bottom=$(echo "scale=9; $bottom+$bot" | bc) 41&nbsp;#  bottom = $(($bottom + $bot")) 42&nbsp; done 43&nbsp;# ====================================================================  44&nbsp; 45&nbsp;# --------------------------------------------------------------------  46&nbsp;#  Rick Boivie给出了一个对上边循环的修改方案,  47&nbsp;#+ 这个修改更加有效率, 将会节省大概2/3的时间.  48&nbsp; 49&nbsp;# for ((x=1; x &#60;= $months; x++)) 50&nbsp;# do 51&nbsp;#   bottom=$(echo "scale=9; $bottom * $interest_rate + 1" | bc) 52&nbsp;# done 53&nbsp; 54&nbsp; 55&nbsp;#  然后他又想出了一个更加有效率的版本,  56&nbsp;#+ 将会节省95%的时间!  57&nbsp; 58&nbsp;# bottom=`{ 59&nbsp;#     echo "scale=9; bottom=$bottom; interest_rate=$interest_rate" 60&nbsp;#     for ((x=1; x &#60;= $months; x++)) 61&nbsp;#     do 62&nbsp;#          echo 'bottom = bottom * interest_rate + 1' 63&nbsp;#     done 64&nbsp;#     echo 'bottom' 65&nbsp;#     } | bc`       # 在命令替换中嵌入一个'for循环'.  66&nbsp;# -------------------------------------------------------------------------- 67&nbsp;#  另一方面, Frank Wang建议:  68&nbsp;#  bottom=$(echo "scale=9; ($interest_rate^$term-1)/($interest_rate-1)" | bc) 69&nbsp; 70&nbsp;#  因为 . . . 71&nbsp;#  在循环后边的算法 72&nbsp;#+ 事实上是一个等比数列的求和公式.  73&nbsp;#  求和公式是 e0(1-q^n)/(1-q),  74&nbsp;#+ e0是第一个元素, q=e(n+1)/e(n),  75&nbsp;#+ n是元素数量. 76&nbsp;# -------------------------------------------------------------------------- 77&nbsp; 78&nbsp; 79&nbsp; # let "payment = $top/$bottom" 80&nbsp; payment=$(echo "scale=2; $top/$bottom" | bc) 81&nbsp; # 使用2位有效数字来表示美元和美分.  82&nbsp;  83&nbsp; echo 84&nbsp; echo "monthly payment = \$$payment"  # 在总和的前边显示美元符号.  85&nbsp; echo 86&nbsp; 87&nbsp; 88&nbsp; exit 0 89&nbsp; 90&nbsp; 91&nbsp; # 练习:  92&nbsp; #   1) 处理输入允许本金总数中的逗号.  93&nbsp; #   2) 处理输入允许按照百分号和小数点的形式输入利率.  94&nbsp; #   3) 如果你真正想好好编写这个脚本,  95&nbsp; #      那么就扩展这个脚本让它能够打印出完整的分期付款表. </PRE></FONT></TD></TR></TABLE><HR></DIV><DIVCLASS="EXAMPLE"><HR><ANAME="BASE"></A><P><B>例子 12-43. 数制转换</B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="PROGRAMLISTING">  1&nbsp;#!/bin/bash  2&nbsp;##########################################################################  3&nbsp;# 脚本       :	base.sh - 用不同的数制来打印数字 (Bourne Shell)  4&nbsp;# 作者       :	Heiner Steven (heiner.steven@odn.de)  5&nbsp;# 日期       :	07-03-95  6&nbsp;# 类型       :	桌面  7&nbsp;# $Id: base.sh,v 1.2 2000/02/06 19:55:35 heiner Exp $  8&nbsp;# ==&#62; 上边这行是RCS ID信息.   9&nbsp;########################################################################## 10&nbsp;# 描述 11&nbsp;# 12&nbsp;# 修改纪录 13&nbsp;# 21-03-95 stv	fixed error occuring with 0xb as input (0.2) 14&nbsp;########################################################################## 15&nbsp; 16&nbsp;# ==&#62; 在本书中使用这个脚本通过了原作者的授权.  17&nbsp;# ==&#62; 注释是本书作者添加的.  18&nbsp; 19&nbsp;NOARGS=65 20&nbsp;PN=`basename "$0"`			       # 程序名 21&nbsp;VER=`echo '$Revision: 1.2 $' | cut -d' ' -f2`  # ==&#62; VER=1.2 22&nbsp; 23&nbsp;Usage () { 24&nbsp;    echo "$PN - print number to different bases, $VER (stv '95) 25&nbsp;usage: $PN [number ...] 26&nbsp; 27&nbsp;If no number is given, the numbers are read from standard input. 28&nbsp;A number may be 29&nbsp;    binary (base 2)		starting with 0b (i.e. 0b1100) 30&nbsp;    octal (base 8)		starting with 0  (i.e. 014) 31&nbsp;    hexadecimal (base 16)	starting with 0x (i.e. 0xc) 32&nbsp;    decimal			otherwise (i.e. 12)" &#62;&#38;2 33&nbsp;    exit $NOARGS  34&nbsp;}   # ==&#62; 打印出用法信息的函数.  35&nbsp; 36&nbsp;Msg () { 37&nbsp;    for i   # ==&#62; 省略[list]. 38&nbsp;    do echo "$PN: $i" &#62;&#38;2 39&nbsp;    done 40&nbsp;} 41&nbsp; 42&nbsp;Fatal () { Msg "$@"; exit 66; } 43&nbsp; 44&nbsp;PrintBases () { 45&nbsp;    # 决定数字的数制 46&nbsp;    for i      # ==&#62; 省略[list]... 47&nbsp;    do         # ==&#62; 所以是对命令行参数进行操作.  48&nbsp;	case "$i" in 49&nbsp;	    0b*)		ibase=2;;	# 2进制 50&nbsp;	    0x*|[a-f]*|[A-F]*)	ibase=16;;	# 16进制 51&nbsp;	    0*)			ibase=8;;	# 8进制 52&nbsp;	    [1-9]*)		ibase=10;;	# 10进制 53&nbsp;	    *) 54&nbsp;		Msg "illegal number $i - ignored" 55&nbsp;		continue;; 56&nbsp;	esac 57&nbsp; 58&nbsp;	# 去掉前缀, 将16进制数字转换为大写(bc命令需要这么做) 59&nbsp;	number=`echo "$i" | sed -e 's:^0[bBxX]::' | tr '[a-f]' '[A-F]'` 60&nbsp;	# ==&#62; 使用":" 作为sed分隔符, 而不使用"/". 61&nbsp; 62&nbsp;	# 将数字转换为10进制 63&nbsp;	dec=`echo "ibase=$ibase; $number" | bc`  # ==&#62; 'bc'是个计算工具. 64&nbsp;	case "$dec" in 65&nbsp;	    [0-9]*)	;;			 # 数字没问题 66&nbsp;	    *)		continue;;		 # 错误: 忽略 67&nbsp;	esac 68&nbsp; 69&nbsp;	# 在一行上打印所有转换后的数字.  70&nbsp;	# ==&#62; 'here document'提供命令列表给'bc'.  71&nbsp;	echo `bc &#60;&#60;! 72&nbsp;	    obase=16; "hex="; $dec 73&nbsp;	    obase=10; "dec="; $dec 74&nbsp;	    obase=8;  "oct="; $dec 75&nbsp;	    obase=2;  "bin="; $dec 76&nbsp;! 77&nbsp;    ` | sed -e 's: :	:g' 78&nbsp; 79&nbsp;    done 80&nbsp;} 81&nbsp; 82&nbsp;while [ $# -gt 0 ] 83&nbsp;# ==&#62;  这里必须使用一个"while循环",  84&nbsp;# ==&#62;+ 因为所有的case都可能退出循环或者 85&nbsp;# ==&#62;+ 结束脚本.  86&nbsp;# ==&#62; (感谢, Paulo Marcel Coelho Aragao.) 87&nbsp;do 88&nbsp;    case "$1" in 89&nbsp;	--)     shift; break;; 90&nbsp;	-h)     Usage;;                 # ==&#62; 帮助信息.  91&nbsp;	-*)     Usage;; 92&nbsp;         *)     break;;			# 第一个数字 93&nbsp;    esac   # ==&#62; 对于非法输入进行更严格检查是非常有用的.  94&nbsp;    shift 95&nbsp;done 96&nbsp; 97&nbsp;if [ $# -gt 0 ] 98&nbsp;then 99&nbsp;    PrintBases "$@"100&nbsp;else					# 从stdin中读取101&nbsp;    while read line102&nbsp;    do103&nbsp;	PrintBases $line104&nbsp;    done105&nbsp;fi106&nbsp;107&nbsp;108&nbsp;exit 0</PRE></FONT></TD></TR></TABLE><HR></DIV><P>调用<BCLASS="COMMAND">bc</B>的另一种方法就是<AHREF="here-docs.html#HEREDOCREF">here		document</A>, 并把它嵌入到<AHREF="commandsub.html#COMMANDSUBREF">命令替换</A>块中. 	当一个脚本需要将一个选项列表和多个命令传递到<BCLASS="COMMAND">bc</B>中时, 	这种方法就显得非常合适了. </P><P>	      <TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="PROGRAMLISTING">  1&nbsp;variable=`bc &#60;&#60; LIMIT_STRING  2&nbsp;options  3&nbsp;statements  4&nbsp;operations  5&nbsp;LIMIT_STRING  6&nbsp;`  7&nbsp;  8&nbsp;...or...  9&nbsp; 10&nbsp; 11&nbsp;variable=$(bc &#60;&#60; LIMIT_STRING 12&nbsp;options 13&nbsp;statements 14&nbsp;operations 15&nbsp;LIMIT_STRING 16&nbsp;)</PRE></FONT></TD></TR></TABLE>              </P><DIVCLASS="EXAMPLE"><HR><ANAME="ALTBC"></A><P><B>例子 12-44. 使用<SPANCLASS="QUOTE">"here document"</SPAN>来调用<BCLASS="COMMAND">bc</B></B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="PROGRAMLISTING">  1&nbsp;#!/bin/bash  2&nbsp;# 使用命令替换来调用'bc'  3&nbsp;# 并与'here document'相结合.   4&nbsp;  5&nbsp;  6&nbsp;var1=`bc &#60;&#60; EOF  7&nbsp;18.33 * 19.78  8&nbsp;EOF  9&nbsp;` 10&nbsp;echo $var1       # 362.56 11&nbsp; 12&nbsp; 13&nbsp;#  使用$( ... )这种标记法也可以.  14&nbsp;v1=23.53 15&nbsp;v2=17.881 16&nbsp;v3=83.501

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -