i-bash/examples/scripts.noah/number.bash
2009-09-12 16:46:56 +00:00

185 lines
5 KiB
Bash

# number.bash
# Author: Noah Friedman <friedman@prep.ai.mit.edu>
# Created: 1993-02-22
# Last modified: 1993-04-01
# Public domain
# Conversion to bash v2 syntax done by Chet Ramey
# Commentary:
# Code:
#:docstring number:
# Usage: number [number]
#
# Converts decimal integers to english notation. Spaces and commas are
# optional. Numbers 67 digits and larger will overflow this script.
#
# E.g: number 99,000,000,000,000,454
# => ninety-nine quadrillion four hundred fifty-four
#
#:end docstring:
function number ()
{
local result
local val1
local val2
local val3
local d1
local d2
local d3
case "$*" in
*[!0-9,.]* )
echo "number: invalid character in argument." 1>&2
return 1
;;
*.* )
echo "number: fractions not supported (yet)." 1>&2
return 1
;;
esac
result=''
eval set - "`echo ${1+\"$@\"} | sed -n -e '
s/[, ]//g;s/^00*/0/g;s/\(.\)\(.\)\(.\)$/\"\1 \2 \3\"/;
:l
/[0-9][0-9][0-9]/{
s/\([^\" ][^\" ]*\)\([^\" ]\)\([^\" ]\)\([^\" ]\)/\1\"\2 \3 \4\"/g;
t l
}
/^[0-9][0-9][0-9]/s/\([^\" ]\)\([^\" ]\)\([^\" ]\)/\"\1 \2 \3\"/;
/^[0-9][0-9]/s/\([^\" ]\)\([^\" ]\)/\"\1 \2\"/;
/^[0-9]/s/^\([^\" ][^\" ]*\)/\"\1\"/g;s/\"\"/\" \"/g;p;'`"
while test $# -ne 0 ; do
eval `set - $1;
d3='' d2='' d1=''
case $# in
1 ) d1=$1 ;;
2 ) d2=$1 d1=$2 ;;
3 ) d3=$1 d2=$2 d1=$3 ;;
esac
echo "d3=\"${d3}\" d2=\"${d2}\" d1=\"${d1}\""`
val1='' val2='' val3=''
case "${d3}" in
'1' ) val3='one' ;;
'2' ) val3='two' ;;
'3' ) val3='three' ;;
'4' ) val3='four' ;;
'5' ) val3='five' ;;
'6' ) val3='six' ;;
'7' ) val3='seven' ;;
'8' ) val3='eight' ;;
'9' ) val3='nine' ;;
esac
case "${d2}" in
'1' ) val2='teen' ;;
'2' ) val2='twenty' ;;
'3' ) val2='thirty' ;;
'4' ) val2='forty' ;;
'5' ) val2='fifty' ;;
'6' ) val2='sixty' ;;
'7' ) val2='seventy' ;;
'8' ) val2='eighty' ;;
'9' ) val2='ninety' ;;
esac
case "${val2}" in
'teen')
val2=''
case "${d1}" in
'0') val1='ten' ;;
'1') val1='eleven' ;;
'2') val1='twelve' ;;
'3') val1='thirteen' ;;
'4') val1='fourteen' ;;
'5') val1='fifteen' ;;
'6') val1='sixteen' ;;
'7') val1='seventeen' ;;
'8') val1='eighteen' ;;
'9') val1='nineteen' ;;
esac
;;
0 ) : ;;
* )
if test ".${val2}" != '.' && test ".${d1}" != '.0' ; then
val2="${val2}-"
fi
case "${d1}" in
'0') val2="${val2} " ;;
'1') val1='one' ;;
'2') val1='two' ;;
'3') val1='three' ;;
'4') val1='four' ;;
'5') val1='five' ;;
'6') val1='six' ;;
'7') val1='seven' ;;
'8') val1='eight' ;;
'9') val1='nine' ;;
esac
;;
esac
if test ".${val3}" != '.' ; then
result="${result}${val3} hundred "
fi
if test ".${val2}" != '.' ; then
result="${result}${val2}"
fi
if test ".${val1}" != '.' ; then
result="${result}${val1} "
fi
if test ".${d1}${d2}${d3}" != '.000' ; then
case $# in
0 | 1 ) ;;
2 ) result="${result}thousand " ;;
3 ) result="${result}million " ;;
4 ) result="${result}billion " ;;
5 ) result="${result}trillion " ;;
6 ) result="${result}quadrillion " ;;
7 ) result="${result}quintillion " ;;
8 ) result="${result}sextillion " ;;
9 ) result="${result}septillion " ;;
10 ) result="${result}octillion " ;;
11 ) result="${result}nonillion " ;;
12 ) result="${result}decillion " ;;
13 ) result="${result}undecillion " ;;
14 ) result="${result}duodecillion " ;;
15 ) result="${result}tredecillion " ;;
16 ) result="${result}quattuordecillion " ;;
17 ) result="${result}quindecillion " ;;
18 ) result="${result}sexdecillion " ;;
19 ) result="${result}septendecillion " ;;
20 ) result="${result}octodecillion " ;;
21 ) result="${result}novemdecillion " ;;
22 ) result="${result}vigintillion " ;;
* )
echo "Error: number too large (66 digits max)." 1>&2
return 1
;;
esac
fi
shift
done
set - ${result}
case "$*" in
'') set - 'zero' ;;
esac
echo ${1+"$@"}
}
provide number
# number.bash ends here