Computer Programming Contest Preparation

ToolBox - Source for: 3/324/LargeNumber1.c



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