1 /* 2 * Copyright (c) 1988 Regents of the University of California. 3 * All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 */ 7 8 #ifndef lint 9 char copyright[] = 10 "@(#) Copyright (c) 1988 Regents of the University of California.\n\ 11 All rights reserved.\n"; 12 #endif /* not lint */ 13 14 #ifndef lint 15 static char sccsid[] = "@(#)number.c 5.1 (Berkeley) 02/28/91"; 16 #endif /* not lint */ 17 18 #include <stdio.h> 19 #include <ctype.h> 20 21 #define YES 1 22 #define NO 0 23 #define EOS '\0' 24 #define MAXNUM 65 /* biggest number we handle */ 25 26 static char *name1[] = { 27 "", "one", "two", "three", 28 "four", "five", "six", "seven", 29 "eight", "nine", "ten", "eleven", 30 "twelve", "thirteen", "fourteen", "fifteen", 31 "sixteen", "seventeen", "eighteen", "nineteen", 32 }, 33 *name2[] = { 34 "", "ten", "twenty", "thirty", 35 "forty", "fifty", "sixty", "seventy", 36 "eighty", "ninety", 37 }, 38 *name3[] = { 39 "hundred", "thousand", "million", "billion", 40 "trillion", "quadrillion", "quintillion", "sextillion", 41 "septillion", "octillion", "nonillion", "decillion", 42 "undecillion", "duodecillion", "tredecillion", "quattuordecillion", 43 "quindecillion", "sexdecillion", 44 "septendecillion", "octodecillion", 45 "novemdecillion", "vigintillion", 46 }; 47 48 main(argc,argv) 49 int argc; 50 char **argv; 51 { 52 register int cnt; 53 char line[MAXNUM * 2 + 2]; /* MAXNUM '.' MAXNUM '\0' */ 54 55 if (argc > 1) 56 for (cnt = 1;cnt < argc;++cnt) { 57 convert(argv[cnt]); 58 puts("..."); 59 } 60 else 61 while (fgets(line,sizeof(line),stdin)) { 62 convert(line); 63 puts("..."); 64 } 65 exit(0); 66 } 67 68 convert(line) 69 char *line; 70 { 71 register int len, 72 ret; 73 register char *C, 74 *fraction; 75 76 for (fraction = NULL, C = line;*C && *C != '\n';++C) 77 if (!isdigit(*C)) 78 switch(*C) { 79 case '-': 80 if (C != line) 81 usage(NO); 82 break; 83 case '.': 84 if (!fraction) { 85 fraction = C + 1; 86 *C = EOS; 87 break; 88 } 89 default: 90 usage(NO); 91 } 92 *C = EOS; 93 if (*line == '-') { 94 puts("minus"); 95 ++line; 96 } 97 ret = NO; 98 if (len = strlen(line)) { 99 if (len > MAXNUM) 100 usage(YES); 101 ret = unit(len,line); 102 } 103 if (fraction && (len = strlen(fraction))) { 104 if (len > MAXNUM) 105 usage(YES); 106 for (C = fraction;*C;++C) 107 if (*C != '0') { 108 if (ret) 109 puts("and"); 110 if (unit(len,fraction)) { 111 ++ret; 112 pfract(len); 113 } 114 break; 115 } 116 } 117 if (!ret) 118 puts("zero."); 119 } 120 121 unit(len,C) 122 register int len; 123 register char *C; 124 { 125 register int off, 126 ret; 127 128 ret = NO; 129 if (len > 3) { 130 if (len % 3) { 131 off = len % 3; 132 len -= off; 133 if (number(C,off)) { 134 ret = YES; 135 printf(" %s.\n",name3[len / 3]); 136 } 137 C += off; 138 } 139 for (;len > 3;C += 3) { 140 len -= 3; 141 if (number(C,3)) { 142 ret = YES; 143 printf(" %s.\n",name3[len / 3]); 144 } 145 } 146 } 147 if (number(C,len)) { 148 puts("."); 149 ret = YES; 150 } 151 return(ret); 152 } 153 154 number(C,len) 155 register char *C; 156 int len; 157 { 158 register int val, 159 ret; 160 161 ret = 0; 162 switch(len) { 163 case 3: 164 if (*C != '0') { 165 ++ret; 166 printf("%s hundred",name1[*C - '0']); 167 } 168 ++C; 169 /*FALLTHROUGH*/ 170 case 2: 171 val = (C[1] - '0') + (C[0] - '0') * 10; 172 if (val) { 173 if (ret++) 174 putchar(' '); 175 if (val < 20) 176 fputs(name1[val],stdout); 177 else { 178 fputs(name2[val / 10],stdout); 179 if (val % 10) 180 printf("-%s",name1[val % 10]); 181 } 182 } 183 break; 184 case 1: 185 if (*C != '0') { 186 ++ret; 187 fputs(name1[*C - '0'],stdout); 188 } 189 } 190 return(ret); 191 } 192 193 pfract(len) 194 register int len; 195 { 196 static char *pref[] = { "", "ten-", "hundred-" }; 197 198 switch(len) { 199 case 1: 200 puts("tenths."); 201 break; 202 case 2: 203 puts("hundredths."); 204 break; 205 default: 206 printf("%s%sths.\n",pref[len % 3],name3[len / 3]); 207 } 208 } 209 210 usage(toobig) 211 int toobig; 212 { 213 if (toobig) 214 fprintf(stderr,"number: number too large, max %d digits.\n",MAXNUM); 215 fputs("usage: number # ...\n",stderr); 216 exit(-1); 217 } 218