• Home
  • History
  • Annotate
  • only in this directory
1# number.bash
2# Author: Noah Friedman <friedman@prep.ai.mit.edu>
3# Created: 1993-02-22
4# Last modified: 1993-04-01
5# Public domain
6
7# Conversion to bash v2 syntax done by Chet Ramey
8
9# Commentary:
10# Code:
11
12#:docstring number:
13# Usage: number [number]
14#
15# Converts decimal integers to english notation.  Spaces and commas are
16# optional.  Numbers 67 digits and larger will overflow this script.
17#
18# E.g: number 99,000,000,000,000,454
19#      => ninety-nine quadrillion four hundred fifty-four
20#
21#:end docstring:
22
23function number ()
24{
25 local result
26 local val1
27 local val2
28 local val3
29 local d1
30 local d2
31 local d3
32
33   case "$*" in
34      *[!0-9,.]* ) 
35         echo "number: invalid character in argument." 1>&2
36         return 1 
37        ;;
38      *.* ) 
39         echo "number: fractions not supported (yet)." 1>&2
40         return 1 
41        ;;
42   esac
43
44   result=''
45
46   eval set - "`echo ${1+\"$@\"} | sed -n -e '
47      s/[, ]//g;s/^00*/0/g;s/\(.\)\(.\)\(.\)$/\"\1 \2 \3\"/;
48      :l
49      /[0-9][0-9][0-9]/{
50         s/\([^\" ][^\" ]*\)\([^\" ]\)\([^\" ]\)\([^\" ]\)/\1\"\2 \3 \4\"/g;
51         t l
52      }
53      /^[0-9][0-9][0-9]/s/\([^\" ]\)\([^\" ]\)\([^\" ]\)/\"\1 \2 \3\"/;
54      /^[0-9][0-9]/s/\([^\" ]\)\([^\" ]\)/\"\1 \2\"/;
55      /^[0-9]/s/^\([^\" ][^\" ]*\)/\"\1\"/g;s/\"\"/\" \"/g;p;'`"
56
57   while test $# -ne 0 ; do
58      eval `set - $1; 
59            d3='' d2='' d1=''
60            case $# in
61               1 ) d1=$1 ;;
62               2 ) d2=$1 d1=$2 ;;
63               3 ) d3=$1 d2=$2 d1=$3 ;;
64            esac
65            echo "d3=\"${d3}\" d2=\"${d2}\" d1=\"${d1}\""`
66
67      val1='' val2='' val3=''
68
69      case "${d3}" in
70         '1' ) val3='one'   ;;
71         '2' ) val3='two'   ;;
72         '3' ) val3='three' ;;
73         '4' ) val3='four'  ;;
74         '5' ) val3='five'  ;;
75         '6' ) val3='six'   ;;
76         '7' ) val3='seven' ;;
77         '8' ) val3='eight' ;;
78         '9' ) val3='nine'  ;;
79      esac
80
81      case "${d2}" in
82         '1' ) val2='teen'    ;;
83         '2' ) val2='twenty'  ;;
84         '3' ) val2='thirty'  ;;
85         '4' ) val2='forty'   ;;
86         '5' ) val2='fifty'   ;;
87         '6' ) val2='sixty'   ;;
88         '7' ) val2='seventy' ;;
89         '8' ) val2='eighty'  ;;
90         '9' ) val2='ninety'  ;;
91      esac
92
93      case "${val2}" in
94         'teen')
95            val2=''
96            case "${d1}" in
97               '0') val1='ten'       ;;
98               '1') val1='eleven'    ;;
99               '2') val1='twelve'    ;;
100               '3') val1='thirteen'  ;;
101               '4') val1='fourteen'  ;;
102               '5') val1='fifteen'   ;;
103               '6') val1='sixteen'   ;;
104               '7') val1='seventeen' ;;
105               '8') val1='eighteen'  ;;
106               '9') val1='nineteen'  ;;
107            esac
108           ;;
109         0 ) : ;;
110         * )
111            if test ".${val2}" != '.' && test ".${d1}" != '.0' ; then
112               val2="${val2}-"
113            fi
114            case "${d1}" in
115               '0') val2="${val2} " ;;
116               '1') val1='one'    ;;
117               '2') val1='two'    ;;
118               '3') val1='three'  ;;
119               '4') val1='four'   ;;
120               '5') val1='five'   ;;
121               '6') val1='six'    ;;
122               '7') val1='seven'  ;;
123               '8') val1='eight'  ;;
124               '9') val1='nine'   ;;
125            esac
126           ;;
127      esac
128
129      if test ".${val3}" != '.' ; then
130         result="${result}${val3} hundred "
131      fi
132
133      if test ".${val2}" != '.' ; then
134         result="${result}${val2}"
135      fi
136
137      if test ".${val1}" != '.' ; then
138         result="${result}${val1} "
139      fi
140
141      if test ".${d1}${d2}${d3}" != '.000' ; then
142         case $# in
143             0 | 1 ) ;;
144             2 ) result="${result}thousand " ;;
145             3 ) result="${result}million " ;;
146             4 ) result="${result}billion " ;;
147             5 ) result="${result}trillion " ;;
148             6 ) result="${result}quadrillion " ;;
149             7 ) result="${result}quintillion " ;;
150             8 ) result="${result}sextillion " ;;
151             9 ) result="${result}septillion " ;;
152            10 ) result="${result}octillion " ;;
153            11 ) result="${result}nonillion " ;;
154            12 ) result="${result}decillion " ;;
155            13 ) result="${result}undecillion " ;;
156            14 ) result="${result}duodecillion " ;;
157            15 ) result="${result}tredecillion " ;;
158            16 ) result="${result}quattuordecillion " ;;
159            17 ) result="${result}quindecillion " ;;
160            18 ) result="${result}sexdecillion " ;;
161            19 ) result="${result}septendecillion " ;;
162            20 ) result="${result}octodecillion " ;;
163            21 ) result="${result}novemdecillion " ;;
164            22 ) result="${result}vigintillion " ;;
165            * )
166               echo "Error: number too large (66 digits max)." 1>&2
167               return 1
168              ;;
169         esac
170      fi
171
172      shift
173   done
174
175   set - ${result}
176   case "$*" in
177      '') set - 'zero' ;;
178   esac
179
180   echo ${1+"$@"}
181}
182
183provide number
184
185# number.bash ends here
186