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