|
|
1.1 root 1: /*
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
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.
16: */
17:
18: #ifndef lint
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
25: static char sccsid[] = "@(#)number.c 4.5 (Berkeley) 6/27/88";
26: #endif /* not lint */
27:
28: #include <stdio.h>
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",
56: };
57:
58: main(argc,argv)
59: int argc;
60: char **argv;
61: {
62: register int cnt;
63: char line[MAXNUM * 2 + 2]; /* MAXNUM '.' MAXNUM '\0' */
64:
65: if (argc > 1)
66: for (cnt = 1;cnt < argc;++cnt) {
67: convert(argv[cnt]);
68: puts("...");
69: }
70: else
71: while (fgets(line,sizeof(line),stdin)) {
72: convert(line);
73: puts("...");
74: }
75: exit(0);
76: }
77:
78: static
79: convert(line)
80: char *line;
81: {
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;
107: }
108: ret = NO;
109: if (len = strlen(line)) {
110: if (len > MAXNUM)
111: usage(YES);
112: ret = unit(len,line);
113: }
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: }
127: }
128: if (!ret)
129: puts("zero.");
130: }
131:
132: static
133: unit(len,C)
134: register int len;
135: register char *C;
136: {
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);
164: }
165:
166: static
167: number(C,len)
168: register char *C;
169: int len;
170: {
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);
204: }
205:
206: static
207: pfract(len)
208: register int len;
209: {
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: }
222: }
223:
224: static
225: usage(toobig)
226: int toobig;
227: {
228: if (toobig)
229: fprintf(stderr,"number: number too large, max %d digits.\n",MAXNUM);
230: fputs("usage: number # ...\n",stderr);
231: exit(-1);
232: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.