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) 06/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 } 233