LDP/LDP/guide/docbook/abs-guide/monthlypmt.sh

101 lines
3.1 KiB
Bash
Raw Normal View History

2001-07-10 14:25:50 +00:00
#!/bin/bash
# monthlypmt.sh: Calculates monthly payment on a mortgage.
2006-12-20 21:11:55 +00:00
# This is a modification of code in the
#+ "mcalc" (mortgage calculator) package,
#+ by Jeff Schmidt
#+ and
2011-08-29 23:59:19 +00:00
#+ Mendel Cooper (yours truly, the ABS Guide author).
# http://www.ibiblio.org/pub/Linux/apps/financial/mcalc-1.6.tar.gz
2001-07-10 14:25:50 +00:00
echo
echo "Given the principal, interest rate, and term of a mortgage,"
echo "calculate the monthly payment."
bottom=1.0
echo
echo -n "Enter principal (no commas) "
read principal
echo -n "Enter interest rate (percent) " # If 12%, enter "12", not ".12".
read interest_r
echo -n "Enter term (months) "
read term
interest_r=$(echo "scale=9; $interest_r/100.0" | bc) # Convert to decimal.
2006-12-20 21:11:55 +00:00
# ^^^^^^^^^^^^^^^^^ Divide by 100.
2001-09-04 13:27:31 +00:00
# "scale" determines how many decimal places.
2001-07-10 14:25:50 +00:00
interest_rate=$(echo "scale=9; $interest_r/12 + 1.0" | bc)
top=$(echo "scale=9; $principal*$interest_rate^$term" | bc)
2006-12-20 21:11:55 +00:00
# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
# Standard formula for figuring interest.
2001-07-10 14:25:50 +00:00
echo; echo "Please be patient. This may take a while."
let "months = $term - 1"
2002-06-03 14:35:48 +00:00
# ====================================================================
2001-07-10 14:25:50 +00:00
for ((x=$months; x > 0; x--))
do
bot=$(echo "scale=9; $interest_rate^$x" | bc)
bottom=$(echo "scale=9; $bottom+$bot" | bc)
# bottom = $(($bottom + $bot"))
done
2005-10-21 13:31:28 +00:00
# ====================================================================
2002-06-03 14:35:48 +00:00
# --------------------------------------------------------------------
# Rick Boivie pointed out a more efficient implementation
#+ of the above loop, which decreases computation time by 2/3.
# for ((x=1; x <= $months; x++))
2002-06-03 14:35:48 +00:00
# do
# bottom=$(echo "scale=9; $bottom * $interest_rate + 1" | bc)
# done
# And then he came up with an even more efficient alternative,
#+ one that cuts down the run time by about 95%!
# bottom=`{
# echo "scale=9; bottom=$bottom; interest_rate=$interest_rate"
# for ((x=1; x <= $months; x++))
2002-06-03 14:35:48 +00:00
# do
# echo 'bottom = bottom * interest_rate + 1'
# done
# echo 'bottom'
# } | bc` # Embeds a 'for loop' within command substitution.
2005-10-21 13:31:28 +00:00
# --------------------------------------------------------------------------
# On the other hand, Frank Wang suggests:
# bottom=$(echo "scale=9; ($interest_rate^$term-1)/($interest_rate-1)" | bc)
# Because . . .
# The algorithm behind the loop
#+ is actually a sum of geometric proportion series.
# The sum formula is e0(1-q^n)/(1-q),
#+ where e0 is the first element and q=e(n+1)/e(n)
#+ and n is the number of elements.
# --------------------------------------------------------------------------
2002-06-03 14:35:48 +00:00
2001-07-10 14:25:50 +00:00
2001-09-04 13:27:31 +00:00
# let "payment = $top/$bottom"
2001-07-10 14:25:50 +00:00
payment=$(echo "scale=2; $top/$bottom" | bc)
# Use two decimal places for dollars and cents.
echo
echo "monthly payment = \$$payment" # Echo a dollar sign in front of amount.
echo
exit 0
2005-10-21 13:31:28 +00:00
2001-07-10 14:25:50 +00:00
# Exercises:
# 1) Filter input to permit commas in principal amount.
# 2) Filter input to permit interest to be entered as percent or decimal.
# 3) If you are really ambitious,
2006-12-20 21:11:55 +00:00
#+ expand this script to print complete amortization tables.