Commit | Line | Data |
---|---|---|
3ce5f7e7 | 1 | /* |
44d8b20d KB |
2 | * Copyright (c) 1988 Regents of the University of California. |
3 | * All rights reserved. | |
4 | * | |
5 | * Redistribution and use in source and binary forms are permitted | |
f4f66d2c KB |
6 | * provided that the above copyright notice and this paragraph are |
7 | * duplicated in all such forms and that any documentation, | |
8 | * advertising materials, and other materials related to such | |
9 | * distribution and use acknowledge that the software was developed | |
10 | * by the University of California, Berkeley. The name of the | |
11 | * University may not be used to endorse or promote products derived | |
12 | * from this software without specific prior written permission. | |
13 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR | |
14 | * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED | |
15 | * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. | |
3ce5f7e7 | 16 | */ |
e9b5e6c3 | 17 | |
3ce5f7e7 | 18 | #ifndef lint |
44d8b20d KB |
19 | char copyright[] = |
20 | "@(#) Copyright (c) 1988 Regents of the University of California.\n\ | |
21 | All rights reserved.\n"; | |
22 | #endif /* not lint */ | |
23 | ||
24 | #ifndef lint | |
f4f66d2c | 25 | static char sccsid[] = "@(#)number.c 4.5 (Berkeley) %G%"; |
44d8b20d | 26 | #endif /* not lint */ |
b2a69b00 KB |
27 | |
28 | #include <stdio.h> | |
3ce5f7e7 KB |
29 | #include <ctype.h> |
30 | ||
31 | #define YES 1 | |
32 | #define NO 0 | |
33 | #define EOS '\0' | |
34 | #define MAXNUM 65 /* biggest number we handle */ | |
35 | ||
36 | static char *name1[] = { | |
37 | "", "one", "two", "three", | |
38 | "four", "five", "six", "seven", | |
39 | "eight", "nine", "ten", "eleven", | |
40 | "twelve", "thirteen", "fourteen", "fifteen", | |
41 | "sixteen", "seventeen", "eighteen", "nineteen", | |
42 | }, | |
43 | *name2[] = { | |
44 | "", "ten", "twenty", "thirty", | |
45 | "forty", "fifty", "sixty", "seventy", | |
46 | "eighty", "ninety", | |
47 | }, | |
48 | *name3[] = { | |
49 | "hundred", "thousand", "million", "billion", | |
50 | "trillion", "quadrillion", "quintillion", "sextillion", | |
51 | "septillion", "octillion", "nonillion", "decillion", | |
52 | "undecillion", "duodecillion", "tredecillion", "quattuordecillion", | |
53 | "quindecillion", "sexdecillion", | |
54 | "septendecillion", "octodecillion", | |
55 | "novemdecillion", "vigintillion", | |
e9b5e6c3 | 56 | }; |
e9b5e6c3 | 57 | |
3ce5f7e7 KB |
58 | main(argc,argv) |
59 | int argc; | |
60 | char **argv; | |
61 | { | |
62 | register int cnt; | |
63 | char line[MAXNUM * 2 + 2]; /* MAXNUM '.' MAXNUM '\0' */ | |
e9b5e6c3 | 64 | |
3ce5f7e7 KB |
65 | if (argc > 1) |
66 | for (cnt = 1;cnt < argc;++cnt) { | |
67 | convert(argv[cnt]); | |
68 | puts("..."); | |
e9b5e6c3 | 69 | } |
3ce5f7e7 KB |
70 | else |
71 | while (fgets(line,sizeof(line),stdin)) { | |
72 | convert(line); | |
73 | puts("..."); | |
e9b5e6c3 | 74 | } |
3ce5f7e7 | 75 | exit(0); |
e9b5e6c3 KM |
76 | } |
77 | ||
3ce5f7e7 KB |
78 | static |
79 | convert(line) | |
80 | char *line; | |
e9b5e6c3 | 81 | { |
3ce5f7e7 KB |
82 | register int len, |
83 | ret; | |
84 | register char *C, | |
85 | *fraction; | |
86 | ||
87 | for (fraction = NULL, C = line;*C && *C != '\n';++C) | |
88 | if (!isdigit(*C)) | |
89 | switch(*C) { | |
90 | case '-': | |
91 | if (C != line) | |
92 | usage(NO); | |
93 | break; | |
94 | case '.': | |
95 | if (!fraction) { | |
96 | fraction = C + 1; | |
97 | *C = EOS; | |
98 | break; | |
99 | } | |
100 | default: | |
101 | usage(NO); | |
102 | } | |
103 | *C = EOS; | |
104 | if (*line == '-') { | |
105 | puts("minus"); | |
106 | ++line; | |
e9b5e6c3 | 107 | } |
3ce5f7e7 KB |
108 | ret = NO; |
109 | if (len = strlen(line)) { | |
110 | if (len > MAXNUM) | |
111 | usage(YES); | |
112 | ret = unit(len,line); | |
e9b5e6c3 | 113 | } |
3ce5f7e7 KB |
114 | if (fraction && (len = strlen(fraction))) { |
115 | if (len > MAXNUM) | |
116 | usage(YES); | |
117 | for (C = fraction;*C;++C) | |
118 | if (*C != '0') { | |
119 | if (ret) | |
120 | puts("and"); | |
121 | if (unit(len,fraction)) { | |
122 | ++ret; | |
123 | pfract(len); | |
124 | } | |
125 | break; | |
126 | } | |
e9b5e6c3 | 127 | } |
3ce5f7e7 KB |
128 | if (!ret) |
129 | puts("zero."); | |
e9b5e6c3 KM |
130 | } |
131 | ||
3ce5f7e7 KB |
132 | static |
133 | unit(len,C) | |
134 | register int len; | |
135 | register char *C; | |
e9b5e6c3 | 136 | { |
3ce5f7e7 KB |
137 | register int off, |
138 | ret; | |
139 | ||
140 | ret = NO; | |
141 | if (len > 3) { | |
142 | if (len % 3) { | |
143 | off = len % 3; | |
144 | len -= off; | |
145 | if (number(C,off)) { | |
146 | ret = YES; | |
147 | printf(" %s.\n",name3[len / 3]); | |
148 | } | |
149 | C += off; | |
150 | } | |
151 | for (;len > 3;C += 3) { | |
152 | len -= 3; | |
153 | if (number(C,3)) { | |
154 | ret = YES; | |
155 | printf(" %s.\n",name3[len / 3]); | |
156 | } | |
157 | } | |
158 | } | |
159 | if (number(C,len)) { | |
160 | puts("."); | |
161 | ret = YES; | |
162 | } | |
163 | return(ret); | |
e9b5e6c3 KM |
164 | } |
165 | ||
3ce5f7e7 KB |
166 | static |
167 | number(C,len) | |
168 | register char *C; | |
169 | int len; | |
e9b5e6c3 | 170 | { |
3ce5f7e7 KB |
171 | register int val, |
172 | ret; | |
173 | ||
174 | ret = 0; | |
175 | switch(len) { | |
176 | case 3: | |
177 | if (*C != '0') { | |
178 | ++ret; | |
179 | printf("%s hundred",name1[*C - '0']); | |
180 | } | |
181 | ++C; | |
182 | /*FALLTHROUGH*/ | |
183 | case 2: | |
184 | val = (C[1] - '0') + (C[0] - '0') * 10; | |
185 | if (val) { | |
186 | if (ret++) | |
187 | putchar(' '); | |
188 | if (val < 20) | |
189 | fputs(name1[val],stdout); | |
190 | else { | |
191 | fputs(name2[val / 10],stdout); | |
192 | if (val % 10) | |
193 | printf("-%s",name1[val % 10]); | |
194 | } | |
195 | } | |
196 | break; | |
197 | case 1: | |
198 | if (*C != '0') { | |
199 | ++ret; | |
200 | fputs(name1[*C - '0'],stdout); | |
201 | } | |
202 | } | |
203 | return(ret); | |
e9b5e6c3 KM |
204 | } |
205 | ||
3ce5f7e7 KB |
206 | static |
207 | pfract(len) | |
208 | register int len; | |
e9b5e6c3 | 209 | { |
3ce5f7e7 KB |
210 | static char *pref[] = { "", "ten-", "hundred-" }; |
211 | ||
212 | switch(len) { | |
213 | case 1: | |
214 | puts("tenths."); | |
215 | break; | |
216 | case 2: | |
217 | puts("hundredths."); | |
218 | break; | |
219 | default: | |
220 | printf("%s%sths.\n",pref[len % 3],name3[len / 3]); | |
221 | } | |
e9b5e6c3 KM |
222 | } |
223 | ||
3ce5f7e7 KB |
224 | static |
225 | usage(toobig) | |
226 | int toobig; | |
e9b5e6c3 | 227 | { |
3ce5f7e7 KB |
228 | if (toobig) |
229 | fprintf(stderr,"number: number too large, max %d digits.\n",MAXNUM); | |
230 | fputs("usage: number # ...\n",stderr); | |
231 | exit(-1); | |
e9b5e6c3 | 232 | } |