📄 mathc.html
字号:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><HTML><HEAD><TITLE>Math Commands</TITLE><METANAME="GENERATOR"CONTENT="Modular DocBook HTML Stylesheet Version 1.57"><LINKREL="HOME"TITLE="Advanced Bash-Scripting Guide"HREF="index.html"><LINKREL="UP"TITLE="External Filters, Programs and Commands"HREF="external.html"><LINKREL="PREVIOUS"TITLE="Terminal Control Commands"HREF="terminalccmds.html"><LINKREL="NEXT"TITLE="Miscellaneous Commands"HREF="extmisc.html"><METAHTTP-EQUIV="Content-Style-Type"CONTENT="text/css"><LINKREL="stylesheet"HREF="common/kde-common.css"TYPE="text/css"><METAHTTP-EQUIV="Content-Type"CONTENT="text/html; charset=iso-8859-1"><METAHTTP-EQUIV="Content-Language"CONTENT="en"><LINKREL="stylesheet"HREF="common/kde-localised.css"TYPE="text/css"TITLE="KDE-English"><LINKREL="stylesheet"HREF="common/kde-default.css"TYPE="text/css"TITLE="KDE-Default"></HEAD><BODYCLASS="SECT1"BGCOLOR="#FFFFFF"TEXT="#000000"LINK="#AA0000"VLINK="#AA0055"ALINK="#AA0000"STYLE="font-family: sans-serif;"><DIVCLASS="NAVHEADER"><TABLEWIDTH="100%"BORDER="0"CELLPADDING="0"CELLSPACING="0"><TR><THCOLSPAN="3"ALIGN="center">Advanced Bash-Scripting Guide: An in-depth exploration of the art of shell scripting</TH></TR><TR><TDWIDTH="10%"ALIGN="left"VALIGN="bottom"><AHREF="terminalccmds.html">Prev</A></TD><TDWIDTH="80%"ALIGN="center"VALIGN="bottom">Chapter 12. External Filters, Programs and Commands</TD><TDWIDTH="10%"ALIGN="right"VALIGN="bottom"><AHREF="extmisc.html">Next</A></TD></TR></TABLE><HRALIGN="LEFT"WIDTH="100%"></DIV><DIVCLASS="SECT1"><H1CLASS="SECT1"><ANAME="MATHC">12.8. Math Commands</A></H1><DIVCLASS="VARIABLELIST"><P><B><ANAME="MATHCOMMANDLISTING1"></A><SPANCLASS="QUOTE">"Doing the numbers"</SPAN></B></P><DL><DT><BCLASS="COMMAND">factor</B></DT><DD><P>Decompose an integer into prime factors.</P><P> <TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><PRECLASS="SCREEN"> <TTCLASS="PROMPT">bash$ </TT><TTCLASS="USERINPUT"><B>factor 27417</B></TT> <TTCLASS="COMPUTEROUTPUT">27417: 3 13 19 37</TT> </PRE></TD></TR></TABLE> </P></DD><DT><ANAME="BCREF"></A><BCLASS="COMMAND">bc</B></DT><DD><P>Bash can't handle floating point calculations, and it lacks operators for certain important mathematical functions. Fortunately, <BCLASS="COMMAND">bc</B> comes to the rescue.</P><P>Not just a versatile, arbitrary precision calculation utility, <BCLASS="COMMAND">bc</B> offers many of the facilities of a programming language.</P><P><BCLASS="COMMAND">bc</B> has a syntax vaguely resembling C.</P><P>Since it is a fairly well-behaved UNIX utility, and may therefore be used in a <AHREF="special-chars.html#PIPEREF">pipe</A>, <BCLASS="COMMAND">bc</B> comes in handy in scripts.</P><P>Here is a simple template for using <BCLASS="COMMAND">bc</B> to calculate a script variable. This uses <AHREF="commandsub.html#COMMANDSUBREF">command substitution</A>.</P><P> <TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><PRECLASS="SCREEN"> <TTCLASS="USERINPUT"><B>variable=$(echo "OPTIONS; OPERATIONS" | bc)</B></TT> </PRE></TD></TR></TABLE> </P><DIVCLASS="EXAMPLE"><HR><ANAME="MONTHLYPMT"></A><P><B>Example 12-42. Monthly Payment on a Mortgage</B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><PRECLASS="PROGRAMLISTING"> 1 #!/bin/bash 2 # monthlypmt.sh: Calculates monthly payment on a mortgage. 3 4 5 # This is a modification of code in the "mcalc" (mortgage calculator) package, 6 #+ by Jeff Schmidt and Mendel Cooper (yours truly, the author of this document). 7 # http://www.ibiblio.org/pub/Linux/apps/financial/mcalc-1.6.tar.gz [15k] 8 9 echo 10 echo "Given the principal, interest rate, and term of a mortgage," 11 echo "calculate the monthly payment." 12 13 bottom=1.0 14 15 echo 16 echo -n "Enter principal (no commas) " 17 read principal 18 echo -n "Enter interest rate (percent) " # If 12%, enter "12", not ".12". 19 read interest_r 20 echo -n "Enter term (months) " 21 read term 22 23 24 interest_r=$(echo "scale=9; $interest_r/100.0" | bc) # Convert to decimal. 25 # "scale" determines how many decimal places. 26 27 28 interest_rate=$(echo "scale=9; $interest_r/12 + 1.0" | bc) 29 30 31 top=$(echo "scale=9; $principal*$interest_rate^$term" | bc) 32 33 echo; echo "Please be patient. This may take a while." 34 35 let "months = $term - 1" 36 # ==================================================================== 37 for ((x=$months; x > 0; x--)) 38 do 39 bot=$(echo "scale=9; $interest_rate^$x" | bc) 40 bottom=$(echo "scale=9; $bottom+$bot" | bc) 41 # bottom = $(($bottom + $bot")) 42 done 43 # ==================================================================== 44 45 # -------------------------------------------------------------------- 46 # Rick Boivie pointed out a more efficient implementation 47 #+ of the above loop, which decreases computation time by 2/3. 48 49 # for ((x=1; x <= $months; x++)) 50 # do 51 # bottom=$(echo "scale=9; $bottom * $interest_rate + 1" | bc) 52 # done 53 54 55 # And then he came up with an even more efficient alternative, 56 #+ one that cuts down the run time by about 95%! 57 58 # bottom=`{ 59 # echo "scale=9; bottom=$bottom; interest_rate=$interest_rate" 60 # for ((x=1; x <= $months; x++)) 61 # do 62 # echo 'bottom = bottom * interest_rate + 1' 63 # done 64 # echo 'bottom' 65 # } | bc` # Embeds a 'for loop' within command substitution. 66 # -------------------------------------------------------------------------- 67 # On the other hand, Frank Wang suggests: 68 # bottom=$(echo "scale=9; ($interest_rate^$term-1)/($interest_rate-1)" | bc) 69 70 # Because . . . 71 # The algorithm behind the loop 72 #+ is actually a sum of geometric proportion series. 73 # The sum formula is e0(1-q^n)/(1-q), 74 #+ where e0 is the first element and q=e(n+1)/e(n) 75 #+ and n is the number of elements. 76 # -------------------------------------------------------------------------- 77 78 79 # let "payment = $top/$bottom" 80 payment=$(echo "scale=2; $top/$bottom" | bc) 81 # Use two decimal places for dollars and cents. 82 83 echo 84 echo "monthly payment = \$$payment" # Echo a dollar sign in front of amount. 85 echo 86 87 88 exit 0 89 90 91 # Exercises: 92 # 1) Filter input to permit commas in principal amount. 93 # 2) Filter input to permit interest to be entered as percent or decimal. 94 # 3) If you are really ambitious, 95 # expand this script to print complete amortization tables.</PRE></TD></TR></TABLE><HR></DIV><DIVCLASS="EXAMPLE"><HR><ANAME="BASE"></A><P><B>Example 12-43. Base Conversion</B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><PRECLASS="PROGRAMLISTING"> 1 #!/bin/bash 2 ########################################################################## 3 # Shellscript: base.sh - print number to different bases (Bourne Shell) 4 # Author : Heiner Steven (heiner.steven@odn.de) 5 # Date : 07-03-95 6 # Category : Desktop 7 # $Id: base.sh,v 1.2 2000/02/06 19:55:35 heiner Exp $ 8 # ==> Above line is RCS ID info. 9 ########################################################################## 10 # Description 11 # 12 # Changes 13 # 21-03-95 stv fixed error occuring with 0xb as input (0.2) 14 ########################################################################## 15 16 # ==> Used in this document with the script author's permission. 17 # ==> Comments added by document author. 18 19 NOARGS=65 20 PN=`basename "$0"` # Program name 21 VER=`echo '$Revision: 1.2 $' | cut -d' ' -f2` # ==> VER=1.2 22 23 Usage () { 24 echo "$PN - print number to different bases, $VER (stv '95) 25 usage: $PN [number ...] 26 27 If no number is given, the numbers are read from standard input. 28 A number may be 29 binary (base 2) starting with 0b (i.e. 0b1100) 30 octal (base 8) starting with 0 (i.e. 014) 31 hexadecimal (base 16) starting with 0x (i.e. 0xc) 32 decimal otherwise (i.e. 12)" >&2 33 exit $NOARGS 34 } # ==> Function to print usage message. 35 36 Msg () { 37 for i # ==> in [list] missing. 38 do echo "$PN: $i" >&2 39 done 40 } 41 42 Fatal () { Msg "$@"; exit 66; } 43 44 PrintBases () { 45 # Determine base of the number 46 for i # ==> in [list] missing... 47 do # ==> so operates on command line arg(s). 48 case "$i" in 49 0b*) ibase=2;; # binary 50 0x*|[a-f]*|[A-F]*) ibase=16;; # hexadecimal 51 0*) ibase=8;; # octal 52 [1-9]*) ibase=10;; # decimal 53 *) 54 Msg "illegal number $i - ignored" 55 continue;; 56 esac 57 58 # Remove prefix, convert hex digits to uppercase (bc needs this) 59 number=`echo "$i" | sed -e 's:^0[bBxX]::' | tr '[a-f]' '[A-F]'` 60 # ==> Uses ":" as sed separator, rather than "/". 61 62 # Convert number to decimal 63 dec=`echo "ibase=$ibase; $number" | bc` # ==> 'bc' is calculator utility. 64 case "$dec" in 65 [0-9]*) ;; # number ok 66 *) continue;; # error: ignore 67 esac 68 69 # Print all conversions in one line. 70 # ==> 'here document' feeds command list to 'bc'. 71 echo `bc <<! 72 obase=16; "hex="; $dec 73 obase=10; "dec="; $dec 74 obase=8; "oct="; $dec 75 obase=2; "bin="; $dec 76 ! 77 ` | sed -e 's: : :g' 78 79 done 80 } 81 82 while [ $# -gt 0 ] 83 # ==> Is a "while loop" really necessary here, 84 # ==>+ since all the cases either break out of the loop 85 # ==>+ or terminate the script. 86 # ==> (Thanks, Paulo Marcel Coelho Aragao.) 87 do 88 case "$1" in 89 --) shift; break;; 90 -h) Usage;; # ==> Help message. 91 -*) Usage;; 92 *) break;; # first number 93 esac # ==> More error checking for illegal input might be useful. 94 shift 95 done 96 97 if [ $# -gt 0 ] 98 then 99 PrintBases "$@" 100 else # read from stdin 101 while read line 102 do 103 PrintBases $line 104 done 105 fi 106 107 108 exit 0</PRE></TD></TR></TABLE><HR></DIV><P>An alternate method of invoking <BCLASS="COMMAND">bc</B> involves using a <AHREF="here-docs.html#HEREDOCREF">here document</A> embedded within a <AHREF="commandsub.html#COMMANDSUBREF">command substitution</A> block. This is especially appropriate when a script needs to pass a list of options and commands to <BCLASS="COMMAND">bc</B>.</P><P> <TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><PRECLASS="PROGRAMLISTING"> 1 variable=`bc << LIMIT_STRING 2 options 3 statements 4 operations 5 LIMIT_STRING 6 ` 7 8 ...or... 9 10 11 variable=$(bc << LIMIT_STRING 12 options 13 statements 14 operations 15 LIMIT_STRING 16 )</PRE></TD></TR></TABLE> </P><DIVCLASS="EXAMPLE"><HR><ANAME="ALTBC"></A><P><B>Example 12-44. Invoking <BCLASS="COMMAND">bc</B> using a <SPANCLASS="QUOTE">"here document"</SPAN></B></P><TABLE
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -