Computer Programming Contest Preparation

ToolBox - Source for: 4/424/e.c



/home/toolbox/public_html/solutions/4/424/e.c
    1 #include <stdio.h>
    2 #include <ctype.h>
    3 #include <string.h>
    4 #include <sys/types.h>
    5 #include <sys/stat.h>
    6 #include <fcntl.h>
    7 #include <stdint.h>
    8 #include <math.h>
    9 #include <stdlib.h>
   10 
   11 #define TRUE  (1 == 1)
   12 #define FALSE (1 != 1)
   13 
   14 #define DEBUG if (FALSE)
   15 
   16 /*
   17  *  Author: Isaac Traxler
   18  *    Date: 2015 02 11
   19  * Purpose:
   20  * Problem: 424
   21  */
   22 
   23 /*
   24  * This template reads data until a terminating value is reached.
   25  */
   26 
   27 
   28 #define LN_MAX_DIGITS 1025
   29 #define MAX_LINE (LN_MAX_DIGITS+25)
   30 
   31 typedef struct LARGE_NUMBER_STRUCT
   32 {
   33     unsigned short int array[LN_MAX_DIGITS]; /* might consider unsigned char here */
   34     /* to reduce storage by 50% */
   35     signed short   int sign;
   36     signed long    int exponent;
   37     signed short   int digitCount;
   38 }
   39 LARGE_NUMBER_STRUCT;
   40 
   41 char buffer[MAX_LINE];
   42 LARGE_NUMBER_STRUCT tot;
   43 LARGE_NUMBER_STRUCT num;
   44 
   45 
   46 void LNprint(LARGE_NUMBER_STRUCT *n)
   47 /* simple routine to print large number */
   48 {
   49     /* BEGIN function LNprint -- (200302) */
   50     char str[LN_MAX_DIGITS+25];
   51 
   52     DEBUG printf("LNprint: 1\n");
   53     DEBUG printf("LNprint: digitCount=%d\n", n->digitCount);
   54     DEBUG printf("LNprint: exponent=%d\n", n->exponent);
   55     DEBUG printf("LNprint: size=%d\n", sizeof(str));
   56     LNarr2strInt(n, str);
   57     DEBUG printf("LNprint: 2\n");
   58     printf("%s\n", str);
   59     DEBUG printf("LNprint: 3\n");
   60 } /* END function LNprint -- (200302)  */
   61 
   62 int LNnegate(LARGE_NUMBER_STRUCT *ln1)
   63 /* changes sign of ln1 */
   64 {
   65     /* BEGIN function LNnegate -- (200302)  */
   66     if (0 != ln1->digitCount)
   67         ln1->sign *= -1;
   68     return 0;
   69 } /* END function LNnegate -- (200302)  */
   70 
   71 int LNcompare(LARGE_NUMBER_STRUCT *ln1, LARGE_NUMBER_STRUCT *ln2)
   72 /* compares to see if a<b (-1), a=b (0), a>b (1); assumes both numbers */
   73 /* are normalized (have first digit non-zero and no trailing zeros) */
   74 {
   75     /* BEGIN function LNcompare -- (200303)  */
   76     int toReturn = 0;
   77 
   78     /* XOR the two, if same 0 (false) results, if different -2 (true)  */
   79     if (ln1->sign ^ ln2->sign) /* signs are same, result is 0  */
   80         {
   81             /* have different signs  */
   82             toReturn = (0 > ln1->sign) ? -1 : 1;
   83         } /* have different signs  */
   84     else
   85         {
   86             /* have same sign  */
   87             if (ln1->exponent != ln2->exponent)
   88                 {
   89                     /* exponents not equal, return 1 (1st one) or -1 (2nd one) to show larger  */
   90                     toReturn = (ln1->exponent > ln2->exponent) ? 1 : -1;
   91                 } /* exponents not equal, return 1 (1st one) or -1 (2nd one) to show larger  */
   92             else
   93                 {
   94                     /* numbers have same exponent */
   95                     int i, t;
   96 
   97                     t = (ln1->digitCount > ln2->digitCount) ? ln2->digitCount : ln1->digitCount;
   98                     for (i=0; (i<t) && (0 == toReturn) ; i++)
   99                         {
  100                             /* for - compare each digit  */
  101                             if (ln1->array[i] != ln2->array[i])
  102                                 toReturn = (ln1->array[i] > ln2->array[i]) ? ln1->sign : - ln2->sign;
  103                         } /* for - compare each digit  */
  104                     /* digits identical, but one number has extra digits, so number with extra digits */
  105                     /* is bigger if positive, smaller if negative. */
  106                     if ((0 == toReturn) && (ln1->digitCount != ln2->digitCount))
  107                         toReturn = (ln1->digitCount > ln2->digitCount) ? ln1->sign : - ln2->sign;
  108                 } /* numbers have same exponent */
  109         } /* have same sign  */
  110     return toReturn;
  111 } /* END function LNcompare -- (200303)  */
  112 
  113 int LNstr2arr(char str[], LARGE_NUMBER_STRUCT *ln)
  114 /* convert from string into LN data structure  */
  115 /* assume no invalid characters in string (but skip over leading and trailing blanks)  */
  116 /* */
  117 /* State diagram: */
  118 /* */
  119 /* state | val | whitespace | -    | +    | .    | digit | Ee   | end of string` */
  120 /* ------+-----+------------+------+------+------+-------+------+-------------- */
  121 /* start | 1   | start      | num1 | num1 | dec1 | num2  | err  | 0 */
  122 /* num1  | 2   | err        | err  | err  | dec1 | num2  | err  | err */
  123 /* num2  | 3   | normalize  | err  | err  | dec2 | num2  | exp1 | normalize */
  124 /* dec1  | 4   | err        | err  | err  | err  | dec2  | err  | err */
  125 /* dec2  | 5   | normalize  | err  | err  | err  | dec2  | exp1 | normalize */
  126 /* exp1  | 6   | err        | exp2 | exp2 | err  | exp3  | err  | err */
  127 /* exp2  | 7   | err        | err  | err  | err  | exp3  | err  | err */
  128 /* exp3  | 8   | normalize  | err  | err  | err  | exp3  | err  | normalize */
  129 {
  130     /* BEGIN function LNstr2arr -- (200302)  */
  131 #define START  1
  132 #define NUM1   2
  133 #define NUM2   3
  134 #define DEC1   4
  135 #define DEC2   5
  136 #define EXP1   6
  137 #define EXP2   7
  138 #define EXP3   8
  139     /* */
  140     /* status -  (succes/failure) flag  (init to SUCCESS)  */
  141     /* done - are we done yet?  (init to NO)  */
  142     /* dpflag - decimal point flag - Have we encountered one yet? (init to NO)  */
  143     /* numflag - number flag - Have we encountered any NON-ZERO digits yet? (init to NO)  */
  144     /* n - counter/subscript for large number (init to start)  */
  145     /* ch - point to main string  */
  146     /* These next two need not be used if their values are stored directly into large number.  */
  147     /*   sign */
  148     /*   exp */
  149     /* */
  150     int state = START, done = 0, n = 0;
  151     signed short int dpflag = 0, numflag = 0, sign = 1;
  152     signed long int exp;
  153     char *ch = str;
  154 
  155     /* skip leading blanks and leading zeroes (start < > start)  */
  156     while ( (isspace(*ch)) || ('0' == *ch) ) ch++;
  157 
  158     if (0 != *ch) /* is it end of string?  */
  159         {
  160             /* not empty string */
  161             /* do we have a sign (must be first char)  */
  162             if ('-' == *ch)
  163                 {
  164                     /* negative - state is NUM1 */
  165                     sign = -1;
  166                     ch++;
  167                 } /* negative - state is NUM1 */
  168             else
  169                 /* Check for plus sign: Not really necessary...(these 4 lines may  */
  170                 /* be omitted) if numbers are not going to have unary pluses */
  171                 if (*ch == '+')
  172                     {
  173                         /* positive (the default) - state is NUM1 */
  174                         ch++;
  175                     } /* positive (the default) - state is NUM1 */
  176 
  177             /* now get digits until the decimal point or exponent */
  178             while (isdigit(*ch))
  179                 {
  180                     /* process digits -- into state NUM2 */
  181                     state = NUM2;
  182                     ln->array[n++] = *ch - '0';
  183                     ch++;  /* move to next char in string */
  184                 } /* process digits -- into state NUM2 */
  185             exp = n;
  186 
  187             if ('.' == *ch)
  188                 {
  189                     /* decimal point  */
  190                     /* set state to DEC1 if no digits, DEC2 if digits already */
  191                     state = (NUM2 != state) ? DEC1 : DEC2;
  192                     ch++;
  193 
  194                     /* now get digits after the decimal point */
  195                     if (isdigit(*ch)) state = DEC2;
  196                     while (isdigit(*ch))
  197                         {
  198                             /* process digits -- into state NUM2 */
  199                             ln->array[n++] = *ch - '0';
  200                             ch++;  /* move to next char in string */
  201                         } /* process digits -- into state NUM2 */
  202                 } /* decimal point */
  203 
  204             /* only things left are Ee (exponent), whitespace and end of string */
  205             if (('E' == *ch) || ('e' == *ch))
  206                 {
  207                     /* okay we have an exponent */
  208                     signed long int texp;
  209 
  210                     state = EXP2;
  211                     ch++;
  212                     sscanf(ch, "%d", &texp);
  213                     exp += texp;
  214                 } /* okay we have an exponent */
  215         } /* not empty string */
  216 
  217     if ((EXP2 == state) || (DEC2 == state) || (NUM2 == state))
  218         {
  219             /* normalize number */
  220             ln->sign = sign;
  221             ln->exponent = exp;
  222             ln->digitCount = n;
  223             state = 0;
  224         } /* normalize number */
  225     return state;
  226 } /* END function LNstr2arr -- (200302)  */
  227 
  228 int LNicnvrt(long int number, LARGE_NUMBER_STRUCT *n)
  229 /* convert a long int to Large Number  */
  230 {
  231     /* BEGIN function LNicnvrt -- (200302)  */
  232     int idx, digit, j;
  233 
  234     /* do sign  */
  235     n->sign = (number < 0) ? -1 : 1;
  236 
  237     /* set mantissa and exponent  */
  238     n->exponent = 0;
  239     idx = LN_MAX_DIGITS;
  240     while (number > 0)
  241         {
  242             /* while  */
  243             digit = number % 10;
  244             n->array[--idx] = digit;
  245             number /= 10;
  246         } /* while  */
  247     n->exponent = LN_MAX_DIGITS - idx;
  248     n->digitCount = n->exponent;
  249     for (j=0; LN_MAX_DIGITS > (j + idx); j++)
  250         {
  251             /* for  */
  252             n->array[j] = n->array[idx+j];
  253         } /* for  */
  254     return 0;
  255 } /* END function LNicnvrt -- (200302)  */
  256 
  257 int LNarr2strExp(LARGE_NUMBER_STRUCT *ln, char str[])
  258 /* convert the ln struct to a string in scientific notation  */
  259 {
  260     /* BEGIN function LNarr2strExp -- (200302)  */
  261     int i, cnt = 0;
  262 
  263     if (0 == ln->digitCount)
  264         {
  265             /* handle zero  */
  266             strncpy("+0E0", str, LN_MAX_DIGITS);
  267         } /* handle zero  */
  268     else
  269         {
  270             /* handle non-zero  */
  271             str[cnt++] = (0 > ln->sign) ? '-' : '+';
  272             str[cnt++] = '0' + ln->array[0];
  273             str[cnt++] = '.';
  274             for (i = 1; i < ln->digitCount; i++)
  275                 str[cnt++] = '0' + ln->array[i];
  276             str[cnt++] = 'E';
  277             sprintf(&(str[cnt]), "%+ld", (ln->exponent-1));
  278         } /* handle non-zero  */
  279     return 0;
  280 } /* END function LNarr2strExp -- (200302)  */
  281 
  282 int LNarr2strInt(LARGE_NUMBER_STRUCT *ln, char str[])
  283 /* convert the ln struct to a string n integer format with truncate  */
  284 {
  285     /* BEGIN function LNarr2strInt -- (200302)  */
  286     int i, cnt = 0;
  287 
  288 
  289     DEBUG printf("LNarr2strInt->exponent=%d\n", ln->exponent);
  290     DEBUG printf("LNarr2strInt->digitCount=%d\n", ln->digitCount);
  291     if ((0 == ln->exponent) && (0 == ln->digitCount))
  292         {
  293             /* abs(number) less than 0 or number is zero */
  294             str[0]='0';
  295             str[1]=0;
  296         } /* abs(number) less than 0 or number is zero */
  297     else if ((0 > ln->exponent) || (0 >= ln->digitCount))
  298         {
  299             /* abs(number) less than 0 or number is zero */
  300             strncpy("+0", str, LN_MAX_DIGITS);
  301         } /* abs(number) less than 0 or number is zero */
  302     else
  303         {
  304             /* something to convert */
  305             int x;
  306 
  307             /* str[cnt++] = (0 > ln->sign) ? '-' : '+';  */
  308             x = (ln->exponent > ln->digitCount) ? ln->digitCount : ln->exponent;
  309             for (i = 0; i < x; i++)
  310                 str[cnt++] = '0' + ln->array[i];
  311             x = ln->exponent - ln->digitCount;
  312             for (i=0; i < x; i++)
  313                 str[cnt++] = '0';
  314             str[cnt] = 0;
  315         } /* something to convert  */
  316     return 0;
  317 } /* END function LNstrInt -- (200302)  */
  318 
  319 int LNln2strFloat(LARGE_NUMBER_STRUCT *ln, char str[])
  320 /* convert the ln struct to a string in float format  */
  321 {
  322     /* BEGIN function LNln2strFloat -- (200302)  */
  323     int i, cnt = 0;
  324 
  325     if (0 == ln->digitCount)
  326         {
  327             /* hadle 0  */
  328             strncpy("+0.0", str, LN_MAX_DIGITS);
  329         } /* hadle 0  */
  330     else
  331         {
  332             /* not zero  */
  333             int x1, x2;
  334 
  335             str[cnt++] = (0 > ln->sign) ? '-' : '+';
  336             x1 = (ln->exponent > ln->digitCount) ? ln->digitCount : ln->exponent;
  337             for (i = 0; i < x1; i++)
  338                 str[cnt++] = '0' + ln->array[i];
  339             x2 = ln->exponent - ln->digitCount;
  340             if (0 > x2)
  341                 {
  342                     /* digitCount larger */
  343                     str[cnt++] = '.';
  344                     for (i = x1; i < ln->digitCount; i++)
  345                         str[cnt++] = '0' + ln->array[i];
  346                 } /* digitCount larger */
  347             else
  348                 {
  349                     /* exponent larger */
  350                     for (i=0; i < x2; i++)
  351                         str[cnt++] = '0';
  352                     str[cnt++] = '.';
  353                     str[cnt++] = '0';
  354                 } /* exponent larger */
  355             str[cnt++] = 0;
  356         } /* not zero  */
  357     return 0;
  358 } /* END function LNstrFloat -- (200302)  */
  359 
  360 int LNshift(LARGE_NUMBER_STRUCT *ln, int cnt)
  361 /* shift the implied decimal point  */
  362 {
  363     /* BEGIN function LiNshift -- (200302)  */
  364     /* errorLevel - Errorlevel to return.  */
  365     /* i - Loop variable.  */
  366     int i, errorLevel = 0;
  367 
  368     if (0 < ln->digitCount)
  369         if (0 < cnt)
  370             {
  371                 /* non-negative - do the shift */
  372                 for ((i = ln->digitCount - 1); i >= 0 ; i --)
  373                     ln->array[i + cnt] = ln->array[i];
  374                 for (i = 0; i < cnt; i ++)
  375                     ln->array[i] = 0;
  376                 ln->exponent += cnt;
  377                 ln->digitCount += cnt;
  378             } /* non-negative - do the shift */
  379         else if (0 != cnt)
  380             {
  381                 /* can't do it */
  382                 fprintf (stderr, "Error: Cannot shift negative bits.\n");
  383                 errorLevel = 1;
  384             } /* can't do it */
  385     return errorLevel;
  386 } /* END function LNshift -- (200302)  */
  387 
  388 int LNnormalize(LARGE_NUMBER_STRUCT *ln)
  389 /* fix LN so that arr[0] <> 0 (if possible)  */
  390 {
  391     /* BEGIN function LNnormalize -- (200302)  */
  392     /* errorLevel - Errorlevel to return.  */
  393     /* zeroCount - How many zeroes?  */
  394     /* i - Loop variable  */
  395     int i, errorLevel = 0, zeroCount = 0;
  396 
  397     if (0 < ln->digitCount)
  398         {
  399             /* digits to process */
  400             while ((ln->array[zeroCount] == 0) && (zeroCount < ln->digitCount))
  401                 {
  402                     /* count leading zeroes */
  403                     zeroCount ++;
  404                 } /* count leading zeroes */
  405             if (0 < zeroCount)
  406                 {
  407                     /* found leading zeroes */
  408                     if (zeroCount == ln->digitCount)
  409                         {
  410                             /* entire number is zero */
  411                             ln->exponent = 0;
  412                             ln->digitCount = 0;
  413                             ln->sign = 1;
  414                         } /* entire number is zero */
  415                     else
  416                         {
  417                             /* digits to shift */
  418                             ln->digitCount -= zeroCount;
  419                             ln->exponent -= zeroCount;
  420                             for (i = 0; i < ln->digitCount; i++)
  421                                 {
  422                                     /* shift them */
  423                                     ln->array[i] = ln->array[i + zeroCount];
  424                                 } /* shift them */
  425                         } /* digits to shift */
  426                 } /* found leading zeroes */
  427             /* handle railing zeroes  */
  428             i = ln->digitCount - 1;
  429             while ((i >= 0) && (0 == ln->array[i]))
  430                 {
  431                     /* while */
  432                     ln->digitCount--;
  433                     i--;
  434                 } /* while */
  435             if (0 == ln->digitCount)
  436                 {
  437                     /* entire number is zero */
  438                     ln->exponent = 0;
  439                     ln->sign = 1;
  440                 } /* entire number is zero */
  441         } /* digits to process */
  442     return (errorLevel);
  443 } /* END function LNnormalize -- (200302)  */
  444 
  445 int LNadd(LARGE_NUMBER_STRUCT *lna, LARGE_NUMBER_STRUCT *lnb,
  446           LARGE_NUMBER_STRUCT *ln3)
  447 /* ln3=ln1+ln2        */
  448 {
  449     /* BEGIN function LNadd  -- (200302)  */
  450     int i, cnt, state = 0, carry = 0;
  451     LARGE_NUMBER_STRUCT ln1, ln2;
  452 
  453     if (0 == lna->digitCount)
  454         *ln3 = *lnb;
  455     else if (0 == lnb->digitCount)
  456         *ln3 = *lna;
  457     else
  458         {
  459             /* add non-zero numbers  */
  460             ln1 = *lna;
  461             ln2 = *lnb;
  462             if (ln1.sign != ln2.sign)
  463                 {
  464                     /* signs different  */
  465                     LNnegate(&ln2);
  466                     state = LNsubtract(&ln1, &ln2, ln3);
  467                 } /* signs different  */
  468             else
  469                 {
  470                     /* signs are same -- continue adding */
  471                     if (ln1.exponent > ln2.exponent)
  472                         {
  473                             /* ln1 is biger */
  474                             LNshift(&ln1, 1);
  475                             LNshift(&ln2, (ln1.exponent - ln2.exponent));
  476                         } /* ln1 is biger */
  477                     else
  478                         {
  479                             /* ln2 is biger */
  480                             LNshift(&ln2, 1);
  481                             LNshift(&ln1, (ln2.exponent - ln1.exponent));
  482                         } /* ln2 is biger */
  483 
  484                     if (ln1.digitCount > ln2.digitCount)
  485                         {
  486                             /* 1 has more digits */
  487                             for (i = ln1.digitCount - 1; i >= ln2.digitCount; i--)
  488                                 ln3->array[i] = ln1.array[i];
  489                             cnt = ln2.digitCount;
  490                             ln3->digitCount = ln1.digitCount;
  491                         } /* 1 has more digits */
  492                     else
  493                         {
  494                             /* 2 has more digits */
  495                             for (i = ln2.digitCount - 1; i >= ln1.digitCount; i--)
  496                                 ln3->array[i] = ln2.array[i];
  497                             cnt = ln1.digitCount;
  498                             ln3->digitCount = ln2.digitCount;
  499                         } /* 2 has more digits */
  500                     /* now actually add */
  501                     ln3->exponent = ln1.exponent;
  502                     for (i = cnt - 1; i >= 0;  i--)
  503                         {
  504                             /* for */
  505                             ln3->array[i] = ln1.array[i] + ln2.array[i] + carry;
  506                             if (ln3->array[i] > 9)
  507                                 {
  508                                     /* set carry */
  509                                     carry = 1;
  510                                     ln3->array[i] -= 10;
  511                                 } /* set carry */
  512                             else
  513                                 {
  514                                     /* reset carry */
  515                                     carry = 0;
  516                                 } /* reset carry */
  517                         } /* for */
  518                     LNnormalize(ln3);
  519                 } /* signs are same -- continue adding */
  520         } /* add non-zero numbers  */
  521     return state;
  522 } /* END function LNadd -- (200302)  */
  523 
  524 int LNsubtract(LARGE_NUMBER_STRUCT *lna, LARGE_NUMBER_STRUCT *lnb,
  525                LARGE_NUMBER_STRUCT *ln3)
  526 /* ln3=ln1-ln2  */
  527 {
  528     /* BEGIN function LNsubtract -- (200303)  */
  529     int toReturn = 0;
  530     LARGE_NUMBER_STRUCT ln1, ln2;
  531 
  532     ln1 = *lna;
  533     ln2 = *lnb;
  534 
  535     if (0 == lna->digitCount)
  536         {
  537             /* first number is zero  */
  538             *ln3 = *lnb;
  539             LNnegate(ln3);
  540         } /* first number is zero  */
  541     else if (0 == lnb->digitCount)
  542         *ln3 = *lna;
  543     else
  544         {
  545             /* subtract non-zero numbers  */
  546             if (ln1.sign != ln2.sign)
  547                 {
  548                     /* signs different  */
  549                     LNnegate(&ln2);
  550                     toReturn = LNadd(&ln1, &ln2, ln3);
  551                 } /* signs different  */
  552             else
  553                 {
  554                     /* signs are same - so subtract    */
  555                     int t, i, tmp, borrow = 0;
  556 
  557                     t = LNcompare(&ln1, &ln2);
  558                     if (0 == t)
  559                         {
  560                             /* same number - return 9  */
  561                             ln3->sign = 1;
  562                             ln3->exponent = 0;
  563                             ln3->digitCount = 0;
  564                         } /* same number - return 9  */
  565                     else if (0 > t)
  566                         {
  567                             /* first number smaller  */
  568                             toReturn = LNsubtract(&ln2, &ln1, ln3);
  569                             ln3->sign = -1 * ln3->sign;
  570                         } /* first number smaller  */
  571                     else
  572                         {
  573                             /* everything okay - actually subtract  */
  574                             ln3->sign = ln1.sign;
  575                             ln3->exponent = ln1.exponent;
  576                             LNshift(&ln2, (ln1.exponent - ln2.exponent));
  577                             if (ln1.digitCount != ln2.digitCount)
  578                                 if (ln1.digitCount > ln2.digitCount)
  579                                     {
  580                                         /* add zeroes to ln2  */
  581                                         for (i=ln2.digitCount; i < ln1.digitCount; i++)
  582                                             ln2.array[i] = 0;
  583                                         ln2.digitCount = ln1.digitCount;
  584                                     } /* add zeroes to ln2  */
  585                                 else
  586                                     {
  587                                         /* add zeroes to ln1  */
  588                                         for (i=ln1.digitCount; i < ln2.digitCount; i++)
  589                                             ln1.array[i] = 0;
  590                                         ln1.digitCount = ln2.digitCount;
  591                                     } /* add zeroes to ln1  */
  592 
  593                             for (i = ln1.digitCount - 1; i >= 0; i--)
  594                                 {
  595                                     /* loop through each digit   */
  596                                     tmp = borrow + ln2.array[i];
  597                                     if (ln1.array[i] > tmp)
  598                                         {
  599                                             /* no borrow  */
  600                                             ln3->array[i] = ln1.array[i] - tmp;
  601                                             borrow = 0;
  602                                         } /* no borrow  */
  603                                     else
  604                                         {
  605                                             /* have to borrow  */
  606                                             ln3->array[i] = (10 + ln1.array[i]) - tmp;
  607                                             borrow = 1;
  608                                         } /* have to borrow  */
  609                                 } /* loop through each digit   */
  610                             LNnormalize(ln3);
  611                         } /* everything okay - actually subtract  */
  612                 } /* signs are same - so subtract    */
  613         } /* subtract non-zero numbers  */
  614     return toReturn;
  615 } /* END function LNsubtract -- (200303)  */
  616 
  617 int LNmultiply(LARGE_NUMBER_STRUCT *ln1, LARGE_NUMBER_STRUCT *ln2,
  618                LARGE_NUMBER_STRUCT *ln3)
  619 /* ln3=ln1*ln2  */
  620 {
  621     /* BEGIN function LNmultiply -- (200303)  */
  622     if ((0 == ln1->digitCount) || (0 == ln2->digitCount))
  623         {
  624             /* multiply by 0 and get 0  */
  625             ln3->digitCount = 0;
  626             ln3->sign = 0;
  627             ln3->exponent = 0;
  628             ln3->array[0] = 0;
  629         } /* multiply by 0 and get 0  */
  630     else
  631         {
  632             /* guess we have to multiply  */
  633             int i1, i2, i3, dig, tmp, carry;
  634 
  635             ln3->sign = ln1->sign * ln2->sign;
  636             ln3->exponent = ln1->exponent + ln2->exponent;
  637             ln3->digitCount = ln1->digitCount + ln2->digitCount;
  638             dig = ln3->digitCount - 1;
  639             /* zero out ln3 so that it can be summed into  */
  640             for (i3=0; i3 <= dig; i3++)
  641                 ln3->array[i3] = 0;
  642             for (i2=ln2->digitCount - 1; i2 >= 0; i2--)
  643                 {
  644                     /* loop through the second numbers digits  */
  645                     carry = 0;
  646                     i3 = dig--;
  647                     for (i1=ln1->digitCount - 1; i1 >= 0; i1--)
  648                         {
  649                             /* process first number  */
  650                             tmp = (ln1->array[i1] * ln2->array[i2]) + carry + ln3->array[i3];
  651                             if (tmp > 9)
  652                                 {
  653                                     /* deal with overflow  */
  654                                     carry = tmp / 10;
  655                                     ln3->array[i3] = (tmp % 10);
  656                                 } /* deal with overflow  */
  657                             else
  658                                 {
  659                                     /* no overflow  */
  660                                     carry = 0;
  661                                     ln3->array[i3] = tmp;
  662                                 } /* no overflow  */
  663                             i3--;
  664                         } /* process first number  */
  665                     ln3->array[i3] = ln3->array[i3] + carry;
  666                 } /* loop through the second numbers digits  */
  667             LNnormalize(ln3);
  668         } /* guess we have to multiply  */
  669     return 0;
  670 } /* END function LNmultiply -- (200303)  */
  671 
  672 int LNdivide(LARGE_NUMBER_STRUCT *ln1, long int i2, LARGE_NUMBER_STRUCT *ln3)
  673 /* ln3=ln1/i2  */
  674 {
  675     /* BEGIN function LNdivide -- (200303)  */
  676     int i, tot = 0;
  677 
  678     ln3->exponent = ln1->exponent;
  679     ln3->sign = ln1->sign * ((0 < i2) ? 1 : -1);
  680     for (i=0; i < ln1->digitCount; i++)
  681         {
  682             /* for each digit  */
  683             tot += ln1->array[i];
  684             if (tot >= i2)
  685                 {
  686                     /* we can divide  */
  687                     ln3->array[i] = tot / i2;
  688                     tot = (tot % i2) * 10;
  689                 } /* we can divide  */
  690             else
  691                 {
  692                     /* can't divide yet, so add a zero  */
  693                     ln3->array[i] = 0;
  694                     tot *= 10;
  695                 } /* can't divide yet, so add a zero  */
  696         } /* for each digit  */
  697 
  698     ln3->digitCount = i;
  699     while ((LN_MAX_DIGITS > ln3->digitCount) && (0 < tot))
  700         {
  701             /* add zeroes on right  */
  702             if (tot >= i2)
  703                 {
  704                     /* we can divide  */
  705                     ln3->array[ln3->digitCount] = tot / i2;
  706                     tot = (tot % i2) * 10;
  707                 } /* we can divide  */
  708             else
  709                 {
  710                     /* can't divide yet, so add a zero  */
  711                     ln3->array[ln3->digitCount] = 0;
  712                     tot *= 10;
  713                 } /* can't divide yet, so add a zero  */
  714             ln3->digitCount++;
  715         } /* add zeroes on right  */
  716     LNnormalize(ln3);
  717     return 0;
  718 } /* END function LNdivide -- (200303)  */
  719 
  720 int LNdcnvrt(double d, LARGE_NUMBER_STRUCT *n)
  721 /* convert a double to Large Number  */
  722 {
  723     /* BEGIN function LNdcnvrt -- (200303)  */
  724     char str[LN_MAX_DIGITS];
  725 
  726     sprintf(str, "%ld:", d);
  727     return LNstr2arr(str, n);
  728 } /* END function LNdcnvrt -- (200303)  */
  729 
  730 int LNcopy(LARGE_NUMBER_STRUCT *ln1, LARGE_NUMBER_STRUCT *ln2)
  731 /* copy from ln1 to ln2  */
  732 {
  733     /* BEGIN function LNcopy -- (200302)  */
  734     int i;
  735 
  736     ln2->sign = ln1->sign;
  737     ln2->exponent = ln1->exponent;
  738     ln2->digitCount = ln1->digitCount;
  739     for (i=0; i < ln1->digitCount; i++)
  740         ln2->array[i] = ln1->array[i];
  741     return 0;
  742 } /* END function LNcopy -- (200302)  */
  743 
  744 
  745 void init()
  746 {
  747     /* FUNCTION init */
  748     buffer[0] = '0';
  749     buffer[1] = 0;
  750     LNstr2arr(buffer, &tot);
  751 } /* FUNCTION init */
  752 
  753 int getInput()
  754 {
  755     /* FUNCTION getInput */
  756     int dataReadFlag;
  757     int i;
  758     int top;
  759 
  760     scanf(" %s ", buffer);
  761     if (0 == strcmp("0", buffer))
  762         {
  763             /* end of file reached */
  764             dataReadFlag = FALSE;
  765         } /* end of file reached */
  766     else
  767         {
  768             /* read in something */
  769             LNstr2arr(buffer, &num);
  770         } /* read in something */
  771     return (dataReadFlag);
  772 } /* FUNCTION getInput */
  773 
  774 void process()
  775 {
  776     /* FUNCTION process */
  777     LNadd(&num, &tot, &tot);
  778 } /* FUNCTION process */
  779 
  780 int main()
  781 {
  782     /* main */
  783     int moreToDo;
  784     int gotInput = FALSE;
  785 
  786     DEBUG printf("Here 1\n");
  787     init();
  788     DEBUG  printf("Here 2\n");
  789     DEBUG printf("tot=");
  790     DEBUG LNprint(&tot);
  791     DEBUG printf("Here 3\n");
  792 
  793     moreToDo = getInput();
  794     while (moreToDo)
  795         {
  796             /* while */
  797             gotInput = TRUE;
  798             DEBUG printf("tot=");
  799             DEBUG LNprint(&tot);
  800             DEBUG printf("num=");
  801             DEBUG LNprint(&num);
  802             process();
  803             moreToDo = getInput();
  804         } /* while */
  805     /* if (gotInput) { LNprint(&tot); } */
  806     LNprint(&tot);
  807 
  808     return EXIT_SUCCESS;
  809 } /* main */
  810