home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / bsd_srcs / games / number / number.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-04-08  |  5.3 KB  |  244 lines

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