Computer Programming Contest Library

[Isaac's Home Page ]  [Fun Page ]  [Class Page ]  [Printable ]  
 Home
 Problem Archive
 Grades
 Tools
 Music
 

Large Number Library

The goal of this library is to produce all the utility routines necessary to work with arbitrarily large numbers.

Large Number Library Source Code

//
// LargeNumber library
//
// authors: Isaac Traxler & students
// 
// This is a project started back in 2000 that was not finished
// and forgotten. It has now been resurrected.
//
// The goal of this project is to produce a usable c source library
// for large number arithmetic.
//
// Students in my Psychology of Programming class in 2000 contributed.
// Since I have largely restructured it, individual names have been 
// removed from the individual routines. So here are the names of the
// original contributing students:
// - Paul Miller
// - Wojciech Stryjewski
// - Phil Bordelon
// - John Walker
// - Erin Valentine
// - Jay Ponville
// - Jamie Ahmad
// - Helen 
//
// Contributed to revamped version:
// - Josh Abadie
// 
#include <ctype.h>
//
// Make sure that LN_MAX_DIGITS is large enough to handle worst case.
// Be aware that as many as 5 LN instances might exist in a routine.
// Be aware that excessively large values will result in CPU consumption
//  in certain situations (like division of repeating decimals).
//  
#define LN_MAX_DIGITS 1000

typedef struct LARGE_NUMBER_STRUCT 
 {
    unsigned short int array[LN_MAX_DIGITS]; // might consider unsigned char here 
                                             // to reduce storage by 50%
    signed short   int sign;
    signed long    int exponent;
    signed short   int digitCount;
 } 
   LARGE_NUMBER_STRUCT;
//
// ASSUMPTIONS:
// 1) That no value sent to the library will exceed bounds
//    a) Exponent will fit into a signed long at ALL times
//    b) Significant digit count will not exceed LN_MAX_DIGITS
//    
// 2) LN instances are ALWAYS normalized when passed into a routine    
// 
// 3) Adding or subtracting two 501 digit numbers can exceed 1000 digits
//
// 4) No bounds checking is done against LN_MAX_DIGITS
//
// 5) Normalization does the following:
//    a) Adjusts exponent, adjusts digitCount, and removes leading zeroes
//    b) Adjusts digitCount and removes trailing zeroes
//    c) Leaves number so that a decimal point is implied before the first digit
//
//
// ********************************************************************************
// rules:
// - all routines return 0 if everything is okay, a different positive number 
//   for each different error
// - Any result passed back (except from LNshift) is normalized
// - LNadd adds any two numbers with same sign (calls subtract if signs differ)
// - LNsubtract subtracts any two numbers with same sign (calls add if signs differ)
// 
// a = 1
// b = -1
// add(a,b,c) ==> subtract(a,(-b),c)
// subtract(a,b,c) ==> add(a,(-b),c)
// 
// - 0 ALWAYS has a + sign and an exponent of 0
// 
//

void LNprint(LARGE_NUMBER_STRUCT *n)
// simple routine to print large number
 { // BEGIN function LNprint -- (200302)
   char str[LN_MAX_DIGITS+25];

   LNarr2strExp(n, str);
   printf("[%s]\n", str);
 } // END function LNprint -- (200302) 

int LNnegate(LARGE_NUMBER_STRUCT *ln1) 
// changes sign of ln1 
 { // BEGIN function LNnegate -- (200302) 
   if (0 != ln1->digitCount)
      ln1->sign *= -1;
   return 0;
 } // END function LNnegate -- (200302) 

int LNcompare(LARGE_NUMBER_STRUCT *ln1, LARGE_NUMBER_STRUCT *ln2)
// compares to see if a<b (-1), a=b (0), a>b (1); assumes both numbers
// are normalized (have first digit non-zero and no trailing zeros)
 { // BEGIN function LNcompare -- (200303) 
   int toReturn = 0;

// XOR the two, if same 0 (false) results, if different -2 (true) 
   if (ln1->sign ^ ln2->sign) // signs are same, result is 0 
    { // have different signs 
      toReturn = (0 > ln1->sign) ? -1 : 1;
    } // have different signs 
   else
    { // have same sign 
      if (ln1->exponent != ln2->exponent)
       { // exponents not equal, return 1 (1st one) or -1 (2nd one) to show larger 
         toReturn = (ln1->exponent > ln2->exponent) ? 1 : -1;
       } // exponents not equal, return 1 (1st one) or -1 (2nd one) to show larger 
      else
       { // numbers have same exponent
         int i, t;

         t = (ln1->digitCount > ln2->digitCount) ? ln2->digitCount : ln1->digitCount;
         for (i=0; (i<t) && (0 == toReturn) ; i++)
          { // for - compare each digit 
            if (ln1->array[i] != ln2->array[i])
               toReturn = (ln1->array[i] > ln2->array[i]) ? ln1->sign : - ln2->sign;
          } // for - compare each digit 
// digits identical, but one number has extra digits, so number with extra digits
// is bigger if positive, smaller if negative.
         if ((0 == toReturn) && (ln1->digitCount != ln2->digitCount))
            toReturn = (ln1->digitCount > ln2->digitCount) ? ln1->sign : - ln2->sign;
       } // numbers have same exponent
    } // have same sign 
   return toReturn;
 } // END function LNcompare -- (200303) 

int LNstr2arr(char str[], LARGE_NUMBER_STRUCT *ln) 
// convert from string into LN data structure 
// assume no invalid characters in string (but skip over leading and trailing blanks) 
//
// State diagram:
//
// state | val | whitespace | -    | +    | .    | digit | Ee   | end of string`
// ------+-----+------------+------+------+------+-------+------+--------------
// start | 1   | start      | num1 | num1 | dec1 | num2  | err  | 0
// num1  | 2   | err        | err  | err  | dec1 | num2  | err  | err
// num2  | 3   | normalize  | err  | err  | dec2 | num2  | exp1 | normalize
// dec1  | 4   | err        | err  | err  | err  | dec2  | err  | err
// dec2  | 5   | normalize  | err  | err  | err  | dec2  | exp1 | normalize
// exp1  | 6   | err        | exp2 | exp2 | err  | exp3  | err  | err
// exp2  | 7   | err        | err  | err  | err  | exp3  | err  | err
// exp3  | 8   | normalize  | err  | err  | err  | exp3  | err  | normalize
{ // BEGIN function LNstr2arr -- (200302) 
#define START  1
#define NUM1   2
#define NUM2   3
#define DEC1   4
#define DEC2   5
#define EXP1   6
#define EXP2   7
#define EXP3   8
//
// status -  (succes/failure) flag  (init to SUCCESS) 
// done - are we done yet?  (init to NO) 
// dpflag - decimal point flag - Have we encountered one yet? (init to NO) 
// numflag - number flag - Have we encountered any NON-ZERO digits yet? (init to NO) 
// n - counter/subscript for large number (init to start) 
// ch - point to main string 
// These next two need not be used if their values are stored directly into large number. 
//   sign
//   exp
//
   int state = START, done = 0, n = 0;
   signed short int dpflag = 0, numflag = 0, sign = 1;
   signed long int exp;
   char *ch = str;

// skip leading blanks and leading zeroes (start < > start) 
   while ( (isspace(*ch)) || ('0' == *ch) ) ch++;

   if (0 != *ch) // is it end of string? 
    { // not empty string
// do we have a sign (must be first char) 
      if ('-' == *ch)
       { // negative - state is NUM1
         sign = -1;
         ch++;
       } // negative - state is NUM1
      else 
// Check for plus sign: Not really necessary...(these 4 lines may 
// be omitted) if numbers are not going to have unary pluses
         if (*ch == '+')
          { // positive (the default) - state is NUM1
            ch++;
          } // positive (the default) - state is NUM1

// now get digits until the decimal point or exponent
      while (isdigit(*ch))
       { // process digits -- into state NUM2
         state = NUM2;
         ln->array[n++] = *ch - '0';
         ch++;  // move to next char in string
       } // process digits -- into state NUM2
      exp = n;

      if ('.' == *ch)
       { // decimal point 
// set state to DEC1 if no digits, DEC2 if digits already
         state = (NUM2 != state) ? DEC1 : DEC2;
         ch++;
           
// now get digits after the decimal point
         if (isdigit(*ch)) state = DEC2;
         while (isdigit(*ch))
          { // process digits -- into state NUM2
            ln->array[n++] = *ch - '0';
            ch++;  // move to next char in string
          } // process digits -- into state NUM2
       } // decimal point
       
// only things left are Ee (exponent), whitespace and end of string
      if (('E' == *ch) || ('e' == *ch))
       { // okay we have an exponent
         signed long int texp;
           
         state = EXP2;
         ch++;
         sscanf(ch, "%d", &texp);
         exp += texp;
        } // okay we have an exponent
    } // not empty string

   if ((EXP2 == state) || (DEC2 == state) || (NUM2 == state))
    { // normalize number
      ln->sign = sign;
      ln->exponent = exp;
      ln->digitCount = n;
      state = 0;
    } // normalize number
   return state;
} // END function LNstr2arr -- (200302) 

int LNicnvrt(long int number, LARGE_NUMBER_STRUCT *n) 
// convert a long int to Large Number 
 { // BEGIN function LNicnvrt -- (200302) 
   int idx, digit, j;

// do sign 
   n->sign = (number < 0) ? -1 : 1;
 
// set mantissa and exponent 
   n->exponent = 0;
   idx = LN_MAX_DIGITS;
   while (number > 0) 
    { // while 
      digit = number % 10;
      n->array[--idx] = digit;
      number /= 10;
    } // while 
   n->exponent = LN_MAX_DIGITS - idx;
   n->digitCount = n->exponent;
   for (j=0; LN_MAX_DIGITS > (j + idx); j++)
    { // for 
      n->array[j] = n->array[idx+j];
    } // for 
   return 0;
 } // END function LNicnvrt -- (200302) 

int LNarr2strExp(LARGE_NUMBER_STRUCT *ln, char str[]) 
// convert the ln struct to a string in scientific notation 
 { // BEGIN function LNarr2strExp -- (200302) 
   int i, cnt = 0;
   
   if (0 == ln->digitCount)
    { // handle zero 
      strncpy("+0E0", str);
    } // handle zero 
   else
    { // handle non-zero 
      str[cnt++] = (0 > ln->sign) ? '-' : '+'; 
      str[cnt++] = '0' + ln->array[0];
      str[cnt++] = '.';
      for (i = 1; i < ln->digitCount; i++)
         str[cnt++] = '0' + ln->array[i];
      str[cnt++] = 'E';
      sprintf(&(str[cnt]), "%+ld", (ln->exponent-1));
    } // handle non-zero 
   return 0;
 } // END function LNarr2strExp -- (200302) 

int LNarr2strInt(LARGE_NUMBER_STRUCT *ln, char str[]) 
// convert the ln struct to a string n integer format with truncate 
 { // BEGIN function LNarr2strInt -- (200302) 
   int i, cnt = 0;
 
   if ((0 > ln->exponent) || (0 >= ln->digitCount))
    { // abs(number) less than 0 or number is zero
      strncpy("+0", str);
    } // abs(number) less than 0 or number is zero
   else
    { // something to convert
      int x;
        
      str[cnt++] = (0 > ln->sign) ? '-' : '+'; 
      x = (ln->exponent > ln->digitCount) ? ln->digitCount : ln->exponent;
      for (i = 0; i < x; i++)
         str[cnt++] = '0' + ln->array[i];
       x = ln->exponent - ln->digitCount;
       for (i=0; i < x; i++)
          str[cnt++] = '0';
       str[cnt] = 0;
    } // something to convert 
   return 0;
 } // END function LNstrInt -- (200302) 

int LNln2strFloat(LARGE_NUMBER_STRUCT *ln, char str[]) 
// convert the ln struct to a string in float format 
 { // BEGIN function LNln2strFloat -- (200302) 
   int i, cnt = 0;
 
   if (0 == ln->digitCount)
    { // hadle 0 
      strncpy("+0.0", str);
     } // hadle 0 
    else
     { // not zero 
       int x1, x2;
        
       str[cnt++] = (0 > ln->sign) ? '-' : '+'; 
       x1 = (ln->exponent > ln->digitCount) ? ln->digitCount : ln->exponent;
       for (i = 0; i < x1; i++)
          str[cnt++] = '0' + ln->array[i];
       x2 = ln->exponent - ln->digitCount;
       if (0 > x2)
        { // digitCount larger
          str[cnt++] = '.';
          for (i = x1; i < ln->digitCount; i++)
             str[cnt++] = '0' + ln->array[i];
        } // digitCount larger
       else
        { // exponent larger
          for (i=0; i < x2; i++)
             str[cnt++] = '0';
          str[cnt++] = '.';
          str[cnt++] = '0';
        } // exponent larger
       str[cnt++] = 0;
     } // not zero 
    return 0;
 } // END function LNstrFloat -- (200302) 

int LNshift(LARGE_NUMBER_STRUCT *ln, int cnt) 
// shift the implied decimal point 
 { // BEGIN function LiNshift -- (200302) 
// errorLevel - Errorlevel to return. 
// i - Loop variable. 
   int i, errorLevel = 0; 

   if (0 < ln->digitCount)
      if (0 < cnt)
       { // non-negative - do the shift
         for ((i = ln->digitCount - 1); i >= 0 ; i --)
            ln->array[i + cnt] = ln->array[i];
         for (i = 0; i < cnt; i ++)
            ln->array[i] = 0;
         ln->exponent += cnt;
         ln->digitCount += cnt;
       } // non-negative - do the shift
      else
         if (0 != cnt)
          { // can't do it
            fprintf (stderr, "Error: Cannot shift negative bits.\n");
            errorLevel = 1;
          } // can't do it
   return errorLevel;
 } // END function LNshift -- (200302) 

int LNnormalize(LARGE_NUMBER_STRUCT *ln) 
// fix LN so that arr[0] <> 0 (if possible) 
 { // BEGIN function LNnormalize -- (200302) 
// errorLevel - Errorlevel to return. 
// zeroCount - How many zeroes? 
// i - Loop variable 
   int i, errorLevel = 0, zeroCount = 0; 

   if (0 < ln->digitCount)
    { // digits to process
      while ((ln->array[zeroCount] == 0) && (zeroCount < ln->digitCount))
       { // count leading zeroes
         zeroCount ++;
       } // count leading zeroes
      if (0 < zeroCount)
       { // found leading zeroes
         if (zeroCount == ln->digitCount)
          { // entire number is zero
            ln->exponent = 0;
            ln->digitCount = 0;
            ln->sign = 1;
          } // entire number is zero
         else
          { // digits to shift
            ln->digitCount -= zeroCount;
            ln->exponent -= zeroCount;
            for (i = 0; i < ln->digitCount; i++)
             { // shift them
               ln->array[i] = ln->array[i + zeroCount];
             } // shift them
          } // digits to shift
       } // found leading zeroes
// handle railing zeroes 
      i = ln->digitCount - 1;
      while ((i >= 0) && (0 == ln->array[i])) 
       { // while
         ln->digitCount--;
         i--;
       } // while
      if (0 == ln->digitCount)
       { // entire number is zero
         ln->exponent = 0;
         ln->sign = 1;
       } // entire number is zero
    } // digits to process
   return (errorLevel);
 } // END function LNnormalize -- (200302) 

int LNadd(LARGE_NUMBER_STRUCT *lna, LARGE_NUMBER_STRUCT *lnb, 
          LARGE_NUMBER_STRUCT *ln3) 
// ln3=ln1+ln2       
 { // BEGIN function LNadd  -- (200302) 
   int i, cnt, state = 0, carry = 0;
   LARGE_NUMBER_STRUCT ln1, ln2;
 
   if (0 == lna->digitCount)
      *ln3 = *lnb;
   else
      if (0 == lnb->digitCount)
         *ln3 = *lna;
      else
       { // add non-zero numbers 
         ln1 = *lna;
         ln2 = *lnb;
         if (ln1.sign != ln2.sign)
          { // signs different 
            LNnegate(&ln2);
            state = LNsubtract(&ln1, &ln2, ln3);
          } // signs different 
         else
          { // signs are same -- continue adding
            if (ln1.exponent > ln2.exponent)
             { // ln1 is biger
               LNshift(&ln1, 1);
               LNshift(&ln2, (ln1.exponent - ln2.exponent));
             } // ln1 is biger
            else
             { // ln2 is biger
               LNshift(&ln2, 1);
               LNshift(&ln1, (ln2.exponent - ln1.exponent));
              } // ln2 is biger
          
            if (ln1.digitCount > ln2.digitCount)
             { // 1 has more digits
               for (i = ln1.digitCount - 1; i >= ln2.digitCount; i--)
                  ln3->array[i] = ln1.array[i];
               cnt = ln2.digitCount;
               ln3->digitCount = ln1.digitCount;
             } // 1 has more digits
            else
             { // 2 has more digits
               for (i = ln2.digitCount - 1; i >= ln1.digitCount; i--)
                  ln3->array[i] = ln2.array[i];
               cnt = ln1.digitCount;
               ln3->digitCount = ln2.digitCount;
             } // 2 has more digits
// now actually add
            ln3->exponent = ln1.exponent;
            for (i = cnt - 1; i >= 0;  i--)
             { // for
               ln3->array[i] = ln1.array[i] + ln2.array[i] + carry;
               if (ln3->array[i] > 9)
                { // set carry
                  carry = 1;
                  ln3->array[i] -= 10;
                } // set carry
               else
                { // reset carry
                  carry = 0;
                } // reset carry
             } // for
            LNnormalize(ln3);
          } // signs are same -- continue adding
       } // add non-zero numbers 
   return state;
 } // END function LNadd -- (200302) 

int LNsubtract(LARGE_NUMBER_STRUCT *lna, LARGE_NUMBER_STRUCT *lnb, 
               LARGE_NUMBER_STRUCT *ln3) 
// ln3=ln1-ln2 
 { // BEGIN function LNsubtract -- (200303) 
   int toReturn = 0;
   LARGE_NUMBER_STRUCT ln1, ln2;
   
   ln1 = *lna;
   ln2 = *lnb;
   
   if (0 == lna->digitCount)
    { // first number is zero 
      *ln3 = *lnb;
      LNnegate(ln3);
    } // first number is zero 
   else
      if (0 == lnb->digitCount)
         *ln3 = *lna;
      else
       { // subtract non-zero numbers 
         if (ln1.sign != ln2.sign)
          { // signs different 
            LNnegate(&ln2);
            toReturn = LNadd(&ln1, &ln2, ln3);
          } // signs different 
         else
          { // signs are same - so subtract   
            int t, i, tmp, borrow = 0;
      
            t = LNcompare(&ln1, &ln2);
            if (0 == t)
             { // same number - return 9 
               ln3->sign = 1;
               ln3->exponent = 0;
               ln3->digitCount = 0;
             } // same number - return 9 
            else
              if (0 > t)
               { // first number smaller 
                 toReturn = LNsubtract(&ln2, &ln1, ln3);
                 ln3->sign = -1 * ln3->sign;
               } // first number smaller 
              else
               { // everything okay - actually subtract 
                 ln3->sign = ln1.sign;
                 ln3->exponent = ln1.exponent;
                 LNshift(&ln2, (ln1.exponent - ln2.exponent)); 
                 if (ln1.digitCount != ln2.digitCount)
                    if (ln1.digitCount > ln2.digitCount)
                     { // add zeroes to ln2 
                       for (i=ln2.digitCount; i < ln1.digitCount; i++)
                          ln2.array[i] = 0;
                       ln2.digitCount = ln1.digitCount;
                     } // add zeroes to ln2 
                    else
                     { // add zeroes to ln1 
                       for (i=ln1.digitCount; i < ln2.digitCount; i++)
                          ln1.array[i] = 0;
                       ln1.digitCount = ln2.digitCount;
                     } // add zeroes to ln1 
                
                 for (i = ln1.digitCount - 1; i >= 0; i--)
                  { // loop through each digit  
                    tmp = borrow + ln2.array[i];
                    if (ln1.array[i] > tmp)
                     { // no borrow 
                       ln3->array[i] = ln1.array[i] - tmp;
                       borrow = 0;
                     } // no borrow 
                    else
                     { // have to borrow 
                       ln3->array[i] = (10 + ln1.array[i]) - tmp;
                       borrow = 1;
                     } // have to borrow 
                  } // loop through each digit  
                 LNnormalize(ln3);
               } // everything okay - actually subtract 
          } // signs are same - so subtract   
       } // subtract non-zero numbers 
   return toReturn;
 } // END function LNsubtract -- (200303) 

int LNmultiply(LARGE_NUMBER_STRUCT *ln1, LARGE_NUMBER_STRUCT *ln2, 
               LARGE_NUMBER_STRUCT *ln3) 
// ln3=ln1*ln2 
 { // BEGIN function LNmultiply -- (200303) 
   if ((0 == ln1->digitCount) || (0 == ln2->digitCount))
    { // multiply by 0 and get 0 
      ln3->digitCount = 0;
      ln3->sign = 0;
      ln3->exponent = 0;
      ln3->array[0] = 0;
    } // multiply by 0 and get 0 
   else
    { // guess we have to multiply 
      int i1, i2, i3, dig, tmp, carry;

      ln3->sign = ln1->sign * ln2->sign;
      ln3->exponent = ln1->exponent + ln2->exponent;
      ln3->digitCount = ln1->digitCount + ln2->digitCount;
      dig = ln3->digitCount - 1;
      // zero out ln3 so that it can be summed into 
      for (i3=0; i3 <= dig; i3++)
         ln3->array[i3] = 0;
      for (i2=ln2->digitCount - 1; i2 >= 0; i2--)
       { // loop through the second numbers digits 
         carry = 0;
         i3 = dig--;
         for (i1=ln1->digitCount - 1; i1 >= 0; i1--)
          { // process first number 
            tmp = (ln1->array[i1] * ln2->array[i2]) + carry + ln3->array[i3];
            if (tmp > 9)
             { // deal with overflow 
               carry = tmp / 10;
               ln3->array[i3] = (tmp % 10);
             } // deal with overflow 
            else
             { // no overflow 
               carry = 0;
               ln3->array[i3] = tmp;
             } // no overflow 
            i3--;
          } // process first number 
         ln3->array[i3] = ln3->array[i3] + carry;
       } // loop through the second numbers digits 
      LNnormalize(ln3);
    } // guess we have to multiply 
    return 0;
 } // END function LNmultiply -- (200303) 

int LNdivide(LARGE_NUMBER_STRUCT *ln1, long int i2, LARGE_NUMBER_STRUCT *ln3) 
// ln3=ln1/i2 
 { // BEGIN function LNdivide -- (200303) 
   int i, tot = 0;

   ln3->exponent = ln1->exponent;
   ln3->sign = ln1->sign * ((0 < i2) ? 1 : -1);
   for (i=0; i < ln1->digitCount; i++)
    { // for each digit 
      tot += ln1->array[i];
      if (tot >= i2)
       { // we can divide 
         ln3->array[i] = tot / i2;
         tot = (tot % i2) * 10;
       } // we can divide 
      else
       { // can't divide yet, so add a zero 
         ln3->array[i] = 0;
         tot *= 10;
       } // can't divide yet, so add a zero 
    } // for each digit 

   ln3->digitCount = i;
   while ((LN_MAX_DIGITS > ln3->digitCount) && (0 < tot))
    { // add zeroes on right 
      if (tot >= i2)
       { // we can divide 
         ln3->array[ln3->digitCount] = tot / i2;
         tot = (tot % i2) * 10;
       } // we can divide 
      else
       { // can't divide yet, so add a zero 
         ln3->array[ln3->digitCount] = 0;
         tot *= 10;
       } // can't divide yet, so add a zero 
      ln3->digitCount++;
    } // add zeroes on right 
   LNnormalize(ln3); 
   return 0;
 } // END function LNdivide -- (200303) 

int LNdcnvrt(double d, LARGE_NUMBER_STRUCT *n) 
// convert a double to Large Number 
 { // BEGIN function LNdcnvrt -- (200303) 
   char str[LN_MAX_DIGITS];
    
   sprintf(str, "%ld:", d);
   return LNstr2arr(str, n);
 } // END function LNdcnvrt -- (200303) 

int LNcopy(LARGE_NUMBER_STRUCT *ln1, LARGE_NUMBER_STRUCT *ln2) 
// copy from ln1 to ln2 
 { // BEGIN function LNcopy -- (200302) 
   int i;

   ln2->sign = ln1->sign;
   ln2->exponent = ln1->exponent;
   ln2->digitCount = ln1->digitCount;
   for (i=0; i < ln1->digitCount; i++) 
      ln2->array[i] = ln1->array[i];
   return 0;
 } // END function LNcopy -- (200302) 

Large Number Example Source Code

#include <stdio.h>
#define DEBUG1 (1 != 1)

#include "LargeNumber.c"

int main ()
 { /* begin FUNCTION main */
    int i;
    LARGE_NUMBER_STRUCT a;    
    LARGE_NUMBER_STRUCT b;    
    LARGE_NUMBER_STRUCT c;    
    int res;
    long int ii;
    char num[1000];
    char tmp[1000];
    
    ii = 123456789;
if (DEBUG1) printf ("A\n");
    res = LNicnvrt(ii, &a);
    printf("------- Display Test ----------\n");
    LNarr2strExp(&a, num);
    printf("LNarr2strExp(a)=%s\n",num);
    LNarr2strInt(&a, num);
    printf("LNarr2strInt(a)=%s\n",num);
    LNln2strFloat(&a, num);
    printf("LNln2strFloat(a)=%s\n",num);
    LNprint(&a);
    printf("-------------------------------\n");

    printf("------- Multiply Test ---------\n");
    LNicnvrt(123, &a);
    LNicnvrt(12, &b);
    LNmultiply(&a, &b, &c);
    LNarr2strInt(&a, num);
    printf("a(%s) * ", num);
    LNarr2strInt(&b, num);
    printf("b(%s) ", num);
    LNarr2strInt(&c, num);
    printf(" = c(%s)\n", num);
    printf("\n");

    printf("-------------------------------\n");

    printf("------- Divide Test ---------\n");
    LNicnvrt(1224, &a);
    LNdivide(&a, 12, &c);
    LNarr2strInt(&a, num);
    printf("a(%s) / 12 ", num);
    LNarr2strExp(&c, num);
    printf(" = c(%s)\n", num);
    printf("\n");

    LNicnvrt(12, &a);
    LNdivide(&a, 12, &c);
    LNarr2strInt(&a, num);
    printf("a(%s) / 12 ", num);
    LNarr2strExp(&c, num);
    printf(" = c(%s)\n", num);
    printf("\n");

    LNicnvrt(1, &a);
    LNdivide(&a, 1, &c);
    LNarr2strInt(&a, num);
    printf("a(%s) / 1 ", num);
    LNarr2strExp(&c, num);
    printf(" = c(%s)\n", num);
    printf("\n");

    LNicnvrt(1, &a);
    LNdivide(&a, 12, &c);
    LNarr2strInt(&a, num);
    printf("a(%s) / 12 ", num);
    LNarr2strExp(&c, num);
    printf(" = c(%s)\n", num);
    printf("\n");

    LNicnvrt(1, &a);
    LNdivide(&a, 125, &c);
    LNarr2strInt(&a, num);
    printf("a(%s) / 125 ", num);
    LNarr2strExp(&c, num);
    printf(" = c(%s)\n", num);

    for (i=100000; i > 0; i = i / 10) {
    LNstr2arr("1111.111111111", &a);
    LNdivide(&a, i, &c);
    LNarr2strInt(&a, num);
    printf("a(%s) / %d ", num, i);
    LNarr2strExp(&c, num);
    printf(" = c(%s)\n", num); }

    tmp = "0.000000000000000000000000000000000000000000000";
    strcat(tmp, "0000000000000000000000000001111111111111");
    LNstr2arr(tmp, &a);
    LNdivide(&a, 10, &c);
    LNarr2strInt(&a, num);
    printf("a(%s) / 10 ", num);
    LNarr2strExp(&c, num);
    printf(" = c(%s)\n", num);

    tmp ="30765988567369.34938637363858653405834085348673";
    strcat(tmp, "4086334739573957397534757357345973497375");
    strcat(tmp, "734573453957");
    LNstr2arr(tmp, &a);
    LNdivide(&a, 123456789, &c);
    LNarr2strInt(&a, num);
    printf("a(%s) / 123456789 ", num);
    LNarr2strExp(&c, num);
    printf(" = c(%s)\n", num);

    printf("\n");

    printf("-------------------------------\n");
    LNicnvrt(123, &a);
if (DEBUG1) printf ("B\n");
    printf("\n");

    printf("-------------------------------\n");
    LNicnvrt(123, &a);
if (DEBUG1) printf ("B\n");
    res = LNcopy(&a,&b);
    b.array[b.exponent] = 3; 
if (DEBUG1) printf ("C\n");
    LNprint(&a);
    printf("%d - %d\n",a.exponent,a.digitCount);
    LNprint(&b);
    printf("%d - %d\n",b.exponent,b.digitCount);
if (DEBUG1) printf ("D\n");
    a.array[0] = 2;
    LNarr2strExp(&a, num);
    printf("arr2str: [%s]\n", num);

    a.array[0] = 3;
    LNarr2strExp(&a, num);
    printf("ln2strExp: [%s]\n", num);

    a.array[0] = 4;
    LNarr2strInt(&a, num);
    printf("ln2strInt: [%s]\n", num);

    a.array[0] = 5;
    a.exponent = 3;
    LNarr2strInt(&a, num);
    printf("ln2strInt: [%s]\n", num);

    a.array[0] = 6;
    a.exponent = 15;
    LNarr2strInt(&a, num);
    printf("ln2strInt: [%s]\n", num);
    
    a.array[0] = 7;
    a.exponent = 7;
    LNln2strFloat(&a, num);
    printf("ln2strFloat: [%s]\n", num);

    LNadd(&a, &b, &c);
    LNarr2strExp(&a, num);
    printf("[%s] + ", num);
    LNarr2strExp(&b, num);
    printf("[%s] = ", num);
    LNarr2strExp(&c, num);
    printf("[%s]\n", num);

    LNsubtract(&a, &b, &c);
    LNarr2strExp(&a, num);
    printf("[%s] - ", num);
    LNarr2strExp(&b, num);
    printf("[%s] = ", num);
    LNarr2strExp(&c, num);
    printf("[%s]\n", num);

    LNsubtract(&b, &a, &c);
    LNarr2strExp(&b, num);
    printf("[%s] - ", num);
    LNarr2strExp(&a, num);
    printf("[%s] = ", num);
    LNarr2strExp(&c, num);
    printf("[%s]\n", num);

 } /* end FUNCTION main */

Large Number Reduced Source Code

#include <ctype.h>
#define LN_MAX_DIGITS 1000

typedef struct LARGE_NUMBER_STRUCT 
 {
    unsigned short int array[LN_MAX_DIGITS]; 
    signed short   int sign;
    signed long    int exponent;
    signed short   int digitCount;
 } 
   LARGE_NUMBER_STRUCT;

void LNprint(LARGE_NUMBER_STRUCT *n)
 { 
   char str[LN_MAX_DIGITS+25];

   LNarr2strExp(n, str);
   printf("[%s]\n", str);
 } 

int LNnegate(LARGE_NUMBER_STRUCT *ln1) 
 { 
   if (0 != ln1->digitCount)
      ln1->sign *= -1;
   return 0;
 } 

int LNcompare(LARGE_NUMBER_STRUCT *ln1, LARGE_NUMBER_STRUCT *ln2)
 { 
   int toReturn = 0;

   if (ln1->sign ^ ln2->sign) 
    { 
      toReturn = (0 > ln1->sign) ? -1 : 1;
    } 
   else
    { 
      if (ln1->exponent != ln2->exponent)
       { 
         toReturn = (ln1->exponent > ln2->exponent) ? 1 : -1;
       } 
      else
       { 
         int i, t;

         t = (ln1->digitCount > ln2->digitCount) ? ln2->digitCount : ln1->digitCount;
         for (i=0; (i<t) && (0 == toReturn) ; i++)
          { 
            if (ln1->array[i] != ln2->array[i])
               toReturn = (ln1->array[i] > ln2->array[i]) ? ln1->sign : - ln2->sign;
          } 
         if ((0 == toReturn) && (ln1->digitCount != ln2->digitCount))
            toReturn = (ln1->digitCount > ln2->digitCount) ? ln1->sign : - ln2->sign;
       } 
    } 
   return toReturn;
 } 

int LNstr2arr(char str[], LARGE_NUMBER_STRUCT *ln) 
{ 
#define START  1
#define NUM1   2
#define NUM2   3
#define DEC1   4
#define DEC2   5
#define EXP1   6
#define EXP2   7
#define EXP3   8
   int state = START, done = 0, n = 0;
   signed short int dpflag = 0, numflag = 0, sign = 1;
   signed long int exp;
   char *ch = str;

   while ( (isspace(*ch)) || ('0' == *ch) ) ch++;

   if (0 != *ch) 
    { 
      if ('-' == *ch)
       { 
         sign = -1;
         ch++;
       } 
      else 
         if (*ch == '+')
          { 
            ch++;
          } 

      while (isdigit(*ch))
       { 
         state = NUM2;
         ln->array[n++] = *ch - '0';
         ch++;  
       } 
      exp = n;

      if ('.' == *ch)
       { 
         state = (NUM2 != state) ? DEC1 : DEC2;
         ch++;
           
         if (isdigit(*ch)) state = DEC2;
         while (isdigit(*ch))
          { 
            ln->array[n++] = *ch - '0';
            ch++;  
          } 
       } 
       
      if (('E' == *ch) || ('e' == *ch))
       { 
         signed long int texp;
           
         state = EXP2;
         ch++;
         sscanf(ch, "%d", &texp);
         exp += texp;
        } 
    } 

   if ((EXP2 == state) || (DEC2 == state) || (NUM2 == state))
    { 
      ln->sign = sign;
      ln->exponent = exp;
      ln->digitCount = n;
      state = 0;
    } 
   return state;
} 

int LNicnvrt(long int number, LARGE_NUMBER_STRUCT *n) 
 { 
   int idx, digit, j;

   n->sign = (number < 0) ? -1 : 1;
 
   n->exponent = 0;
   idx = LN_MAX_DIGITS;
   while (number > 0) 
    { 
      digit = number % 10;
      n->array[--idx] = digit;
      number /= 10;
    } 
   n->exponent = LN_MAX_DIGITS - idx;
   n->digitCount = n->exponent;
   for (j=0; LN_MAX_DIGITS > (j + idx); j++)
    { 
      n->array[j] = n->array[idx+j];
    } 
   return 0;
 } 

int LNarr2strExp(LARGE_NUMBER_STRUCT *ln, char str[]) 
 { 
   int i, cnt = 0;
   
   if (0 == ln->digitCount)
    { 
      strncpy("+0E0", str);
    } 
   else
    { 
      str[cnt++] = (0 > ln->sign) ? '-' : '+'; 
      str[cnt++] = '0' + ln->array[0];
      str[cnt++] = '.';
      for (i = 1; i < ln->digitCount; i++)
         str[cnt++] = '0' + ln->array[i];
      str[cnt++] = 'E';
      sprintf(&(str[cnt]), "%+ld", (ln->exponent-1));
    } 
   return 0;
 } 

int LNarr2strInt(LARGE_NUMBER_STRUCT *ln, char str[]) 
 { 
   int i, cnt = 0;
 
   if ((0 > ln->exponent) || (0 >= ln->digitCount))
    { 
      strncpy("+0", str);
    } 
   else
    { 
      int x;
        
      str[cnt++] = (0 > ln->sign) ? '-' : '+'; 
      x = (ln->exponent > ln->digitCount) ? ln->digitCount : ln->exponent;
      for (i = 0; i < x; i++)
         str[cnt++] = '0' + ln->array[i];
       x = ln->exponent - ln->digitCount;
       for (i=0; i < x; i++)
          str[cnt++] = '0';
       str[cnt] = 0;
    } 
   return 0;
 } 

int LNln2strFloat(LARGE_NUMBER_STRUCT *ln, char str[]) 
 { 
   int i, cnt = 0;
 
   if (0 == ln->digitCount)
    { 
      strncpy("+0.0", str);
     } 
    else
     { 
       int x1, x2;
        
       str[cnt++] = (0 > ln->sign) ? '-' : '+'; 
       x1 = (ln->exponent > ln->digitCount) ? ln->digitCount : ln->exponent;
       for (i = 0; i < x1; i++)
          str[cnt++] = '0' + ln->array[i];
       x2 = ln->exponent - ln->digitCount;
       if (0 > x2)
        { 
          str[cnt++] = '.';
          for (i = x1; i < ln->digitCount; i++)
             str[cnt++] = '0' + ln->array[i];
        } 
       else
        { 
          for (i=0; i < x2; i++)
             str[cnt++] = '0';
          str[cnt++] = '.';
          str[cnt++] = '0';
        } 
       str[cnt++] = 0;
     } 
    return 0;
 } 

int LNshift(LARGE_NUMBER_STRUCT *ln, int cnt) 
 { 
   int i, errorLevel = 0; 

   if (0 < ln->digitCount)
      if (0 < cnt)
       { 
         for ((i = ln->digitCount - 1); i >= 0 ; i --)
            ln->array[i + cnt] = ln->array[i];
         for (i = 0; i < cnt; i ++)
            ln->array[i] = 0;
         ln->exponent += cnt;
         ln->digitCount += cnt;
       } 
      else
         if (0 != cnt)
          { 
            fprintf (stderr, "Error: Cannot shift negative bits.\n");
            errorLevel = 1;
          } 
   return errorLevel;
 } 

int LNnormalize(LARGE_NUMBER_STRUCT *ln) 
 { 
   int i, errorLevel = 0, zeroCount = 0; 

   if (0 < ln->digitCount)
    { 
      while ((ln->array[zeroCount] == 0) && (zeroCount < ln->digitCount))
       { 
         zeroCount ++;
       } 
      if (0 < zeroCount)
       { 
         if (zeroCount == ln->digitCount)
          { 
            ln->exponent = 0;
            ln->digitCount = 0;
            ln->sign = 1;
          } 
         else
          { 
            ln->digitCount -= zeroCount;
            ln->exponent -= zeroCount;
            for (i = 0; i < ln->digitCount; i++)
             { 
               ln->array[i] = ln->array[i + zeroCount];
             } 
          } 
       } 
      i = ln->digitCount - 1;
      while ((i >= 0) && (0 == ln->array[i])) 
       { 
         ln->digitCount--;
         i--;
       } 
      if (0 == ln->digitCount)
       { 
         ln->exponent = 0;
         ln->sign = 1;
       } 
    } 
   return (errorLevel);
 } 

int LNadd(LARGE_NUMBER_STRUCT *lna, LARGE_NUMBER_STRUCT *lnb, 
          LARGE_NUMBER_STRUCT *ln3) 
 { 
   int i, cnt, state = 0, carry = 0;
   LARGE_NUMBER_STRUCT ln1, ln2;
 
   if (0 == lna->digitCount)
      *ln3 = *lnb;
   else
      if (0 == lnb->digitCount)
         *ln3 = *lna;
      else
       { 
         ln1 = *lna;
         ln2 = *lnb;
         if (ln1.sign != ln2.sign)
          { 
            LNnegate(&ln2);
            state = LNsubtract(&ln1, &ln2, ln3);
          } 
         else
          { 
            if (ln1.exponent > ln2.exponent)
             { 
               LNshift(&ln1, 1);
               LNshift(&ln2, (ln1.exponent - ln2.exponent));
             } 
            else
             { 
               LNshift(&ln2, 1);
               LNshift(&ln1, (ln2.exponent - ln1.exponent));
              } 
          
            if (ln1.digitCount > ln2.digitCount)
             { 
               for (i = ln1.digitCount - 1; i >= ln2.digitCount; i--)
                  ln3->array[i] = ln1.array[i];
               cnt = ln2.digitCount;
               ln3->digitCount = ln1.digitCount;
             } 
            else
             { 
               for (i = ln2.digitCount - 1; i >= ln1.digitCount; i--)
                  ln3->array[i] = ln2.array[i];
               cnt = ln1.digitCount;
               ln3->digitCount = ln2.digitCount;
             } 
            ln3->exponent = ln1.exponent;
            for (i = cnt - 1; i >= 0;  i--)
             { 
               ln3->array[i] = ln1.array[i] + ln2.array[i] + carry;
               if (ln3->array[i] > 9)
                { 
                  carry = 1;
                  ln3->array[i] -= 10;
                } 
               else
                { 
                  carry = 0;
                } 
             } 
            LNnormalize(ln3);
          } 
       } 
   return state;
 } 

int LNsubtract(LARGE_NUMBER_STRUCT *lna, LARGE_NUMBER_STRUCT *lnb, 
               LARGE_NUMBER_STRUCT *ln3) 
 { 
   int toReturn = 0;
   LARGE_NUMBER_STRUCT ln1, ln2;
   
   ln1 = *lna;
   ln2 = *lnb;
   
   if (0 == lna->digitCount)
    { 
      *ln3 = *lnb;
      LNnegate(ln3);
    } 
   else
      if (0 == lnb->digitCount)
         *ln3 = *lna;
      else
       { 
         if (ln1.sign != ln2.sign)
          { 
            LNnegate(&ln2);
            toReturn = LNadd(&ln1, &ln2, ln3);
          } 
         else
          { 
            int t, i, tmp, borrow = 0;
      
            t = LNcompare(&ln1, &ln2);
            if (0 == t)
             { 
               ln3->sign = 1;
               ln3->exponent = 0;
               ln3->digitCount = 0;
             } 
            else
              if (0 > t)
               { 
                 toReturn = LNsubtract(&ln2, &ln1, ln3);
                 ln3->sign = -1 * ln3->sign;
               } 
              else
               { 
                 ln3->sign = ln1.sign;
                 ln3->exponent = ln1.exponent;
                 LNshift(&ln2, (ln1.exponent - ln2.exponent)); 
                 if (ln1.digitCount != ln2.digitCount)
                    if (ln1.digitCount > ln2.digitCount)
                     { 
                       for (i=ln2.digitCount; i < ln1.digitCount; i++)
                          ln2.array[i] = 0;
                       ln2.digitCount = ln1.digitCount;
                     } 
                    else
                     { 
                       for (i=ln1.digitCount; i < ln2.digitCount; i++)
                          ln1.array[i] = 0;
                       ln1.digitCount = ln2.digitCount;
                     } 
                
                 for (i = ln1.digitCount - 1; i >= 0; i--)
                  { 
                    tmp = borrow + ln2.array[i];
                    if (ln1.array[i] > tmp)
                     { 
                       ln3->array[i] = ln1.array[i] - tmp;
                       borrow = 0;
                     } 
                    else
                     { 
                       ln3->array[i] = (10 + ln1.array[i]) - tmp;
                       borrow = 1;
                     } 
                  } 
                 LNnormalize(ln3);
               } 
          } 
       } 
   return toReturn;
 } 

int LNmultiply(LARGE_NUMBER_STRUCT *ln1, LARGE_NUMBER_STRUCT *ln2, 
               LARGE_NUMBER_STRUCT *ln3) 
 { 
   if ((0 == ln1->digitCount) || (0 == ln2->digitCount))
    { 
      ln3->digitCount = 0;
      ln3->sign = 0;
      ln3->exponent = 0;
      ln3->array[0] = 0;
    } 
   else
    { 
      int i1, i2, i3, dig, tmp, carry;

      ln3->sign = ln1->sign * ln2->sign;
      ln3->exponent = ln1->exponent + ln2->exponent;
      ln3->digitCount = ln1->digitCount + ln2->digitCount;
      dig = ln3->digitCount - 1;
      for (i3=0; i3 <= dig; i3++)
         ln3->array[i3] = 0;
      for (i2=ln2->digitCount - 1; i2 >= 0; i2--)
       { 
         carry = 0;
         i3 = dig--;
         for (i1=ln1->digitCount - 1; i1 >= 0; i1--)
          { 
            tmp = (ln1->array[i1] * ln2->array[i2]) + carry + ln3->array[i3];
            if (tmp > 9)
             { 
               carry = tmp / 10;
               ln3->array[i3] = (tmp % 10);
             } 
            else
             { 
               carry = 0;
               ln3->array[i3] = tmp;
             } 
            i3--;
          } 
         ln3->array[i3] = ln3->array[i3] + carry;
       } 
      LNnormalize(ln3);
    } 
    return 0;
 } 

int LNdivide(LARGE_NUMBER_STRUCT *ln1, long int i2, LARGE_NUMBER_STRUCT *ln3) 
 { 
   int i, tot = 0;

   ln3->exponent = ln1->exponent;
   ln3->sign = ln1->sign * ((0 < i2) ? 1 : -1);
   for (i=0; i < ln1->digitCount; i++)
    { 
      tot += ln1->array[i];
      if (tot >= i2)
       { 
         ln3->array[i] = tot / i2;
         tot = (tot % i2) * 10;
       } 
      else
       { 
         ln3->array[i] = 0;
         tot *= 10;
       } 
    } 

   ln3->digitCount = i;
   while ((LN_MAX_DIGITS > ln3->digitCount) && (0 < tot))
    { 
      if (tot >= i2)
       { 
         ln3->array[ln3->digitCount] = tot / i2;
         tot = (tot % i2) * 10;
       } 
      else
       { 
         ln3->array[ln3->digitCount] = 0;
         tot *= 10;
       } 
      ln3->digitCount++;
    } 
   LNnormalize(ln3); 
   return 0;
 } 

int LNdcnvrt(double d, LARGE_NUMBER_STRUCT *n) 
 { 
   char str[LN_MAX_DIGITS];
    
   sprintf(str, "%ld:", d);
   return LNstr2arr(str, n);
 } 

int LNcopy(LARGE_NUMBER_STRUCT *ln1, LARGE_NUMBER_STRUCT *ln2) 
 { 
   int i;

   ln2->sign = ln1->sign;
   ln2->exponent = ln1->exponent;
   ln2->digitCount = ln1->digitCount;
   for (i=0; i < ln1->digitCount; i++) 
      ln2->array[i] = ln1->array[i];
   return 0;
 } 

Large Number Minimized Code

#include <ctype.h>
#define LMD 1000

typedef struct LNS 
 {
    unsigned short int a[LMD]; 
    signed short   int sign;
    signed long    int exp;
    signed short   int dc;
 } 
   LNS;

void LNprint(LNS *n)
 { 
   char str[LMD+25];

   LNarr2strExp(n, str);
   printf("[%s]\n", str);
 } 

int LNnegate(LNS *ln1) 
 { 
   if (0 != ln1->dc)
      ln1->sign *= -1;
   return 0;
 } 

int LNcompare(LNS *ln1, LNS *ln2)
 { 
   int ret = 0;

   if (ln1->sign ^ ln2->sign) 
    { 
      ret = (0 > ln1->sign) ? -1 : 1;
    } 
   else
    { 
      if (ln1->exp != ln2->exp)
       { 
         ret = (ln1->exp > ln2->exp) ? 1 : -1;
       } 
      else
       { 
         int i, t;

         t = (ln1->dc > ln2->dc) ? ln2->dc : ln1->dc;
         for (i=0; (i<t) && (0 == ret) ; i++)
          { 
            if (ln1->a[i] != ln2->a[i])
               ret = (ln1->a[i] > ln2->a[i]) ? ln1->sign : - ln2->sign;
          } 
         if ((0 == ret) && (ln1->dc != ln2->dc))
            ret = (ln1->dc > ln2->dc) ? ln1->sign : - ln2->sign;
       } 
    } 
   return ret;
 } 

int LNstr2arr(char str[], LNS *ln) 
{ 
#define START  1
#define NUM1   2
#define NUM2   3
#define DEC1   4
#define DEC2   5
#define EXP1   6
#define EXP2   7
#define EXP3   8
   int state = START, done = 0, n = 0;
   signed short int dpflag = 0, numflag = 0, sign = 1;
   signed long int exp;
   char *ch = str;

   while ( (isspace(*ch)) || ('0' == *ch) ) ch++;

   if (0 != *ch) 
    { 
      if ('-' == *ch)
       { 
         sign = -1;
         ch++;
       } 
      else 
         if (*ch == '+')
          { 
            ch++;
          } 

      while (isdigit(*ch))
       { 
         state = NUM2;
         ln->a[n++] = *ch - '0';
         ch++;  
       } 
      exp = n;

      if ('.' == *ch)
       { 
         state = (NUM2 != state) ? DEC1 : DEC2;
         ch++;
           
         if (isdigit(*ch)) state = DEC2;
         while (isdigit(*ch))
          { 
            ln->a[n++] = *ch - '0';
            ch++;  
          } 
       } 
       
      if (('E' == *ch) || ('e' == *ch))
       { 
         signed long int texp;
           
         state = EXP2;
         ch++;
         sscanf(ch, "%d", &texp);
         exp += texp;
        } 
    } 

   if ((EXP2 == state) || (DEC2 == state) || (NUM2 == state))
    { 
      ln->sign = sign;
      ln->exp = exp;
      ln->dc = n;
      state = 0;
    } 
   return state;
} 

int LNicnvrt(long int number, LNS *n) 
 { 
   int idx, digit, j;

   n->sign = (number < 0) ? -1 : 1;
 
   n->exp = 0;
   idx = LMD;
   while (number > 0) 
    { 
      digit = number % 10;
      n->a[--idx] = digit;
      number /= 10;
    } 
   n->exp = LMD - idx;
   n->dc = n->exp;
   for (j=0; LMD > (j + idx); j++)
    { 
      n->a[j] = n->a[idx+j];
    } 
   return 0;
 } 

int LNarr2strExp(LNS *ln, char str[]) 
 { 
   int i, cnt = 0;
   
   if (0 == ln->dc)
    { 
      strncpy("+0E0", str);
    } 
   else
    { 
      str[cnt++] = (0 > ln->sign) ? '-' : '+'; 
      str[cnt++] = '0' + ln->a[0];
      str[cnt++] = '.';
      for (i = 1; i < ln->dc; i++)
         str[cnt++] = '0' + ln->a[i];
      str[cnt++] = 'E';
      sprintf(&(str[cnt]), "%+ld", (ln->exp-1));
    } 
   return 0;
 } 

int LNarr2strInt(LNS *ln, char str[]) 
 { 
   int i, cnt = 0;
 
   if ((0 > ln->exp) || (0 >= ln->dc))
    { 
      strncpy("+0", str);
    } 
   else
    { 
      int x;
        
      str[cnt++] = (0 > ln->sign) ? '-' : '+'; 
      x = (ln->exp > ln->dc) ? ln->dc : ln->exp;
      for (i = 0; i < x; i++)
         str[cnt++] = '0' + ln->a[i];
       x = ln->exp - ln->dc;
       for (i=0; i < x; i++)
          str[cnt++] = '0';
       str[cnt] = 0;
    } 
   return 0;
 } 

int LNln2strFloat(LNS *ln, char str[]) 
 { 
   int i, cnt = 0;
 
   if (0 == ln->dc)
    { 
      strncpy("+0.0", str);
     } 
    else
     { 
       int x1, x2;
        
       str[cnt++] = (0 > ln->sign) ? '-' : '+'; 
       x1 = (ln->exp > ln->dc) ? ln->dc : ln->exp;
       for (i = 0; i < x1; i++)
          str[cnt++] = '0' + ln->a[i];
       x2 = ln->exp - ln->dc;
       if (0 > x2)
        { 
          str[cnt++] = '.';
          for (i = x1; i < ln->dc; i++)
             str[cnt++] = '0' + ln->a[i];
        } 
       else
        { 
          for (i=0; i < x2; i++)
             str[cnt++] = '0';
          str[cnt++] = '.';
          str[cnt++] = '0';
        } 
       str[cnt++] = 0;
     } 
    return 0;
 } 

int LNshift(LNS *ln, int cnt) 
 { 
   int i, errorLevel = 0; 

   if (0 < ln->dc)
      if (0 < cnt)
       { 
         for ((i = ln->dc - 1); i >= 0 ; i --)
            ln->a[i + cnt] = ln->a[i];
         for (i = 0; i < cnt; i ++)
            ln->a[i] = 0;
         ln->exp += cnt;
         ln->dc += cnt;
       } 
      else
         if (0 != cnt)
          { 
            fprintf (stderr, "Error: Cannot shift negative bits.\n");
            errorLevel = 1;
          } 
   return errorLevel;
 } 

int LNnormalize(LNS *ln) 
 { 
   int i, errorLevel = 0, zeroCount = 0; 

   if (0 < ln->dc)
    { 
      while ((ln->a[zeroCount] == 0) && (zeroCount < ln->dc))
       { 
         zeroCount ++;
       } 
      if (0 < zeroCount)
       { 
         if (zeroCount == ln->dc)
          { 
            ln->exp = 0;
            ln->dc = 0;
            ln->sign = 1;
          } 
         else
          { 
            ln->dc -= zeroCount;
            ln->exp -= zeroCount;
            for (i = 0; i < ln->dc; i++)
             { 
               ln->a[i] = ln->a[i + zeroCount];
             } 
          } 
       } 
      i = ln->dc - 1;
      while ((i >= 0) && (0 == ln->a[i])) 
       { 
         ln->dc--;
         i--;
       } 
      if (0 == ln->dc)
       { 
         ln->exp = 0;
         ln->sign = 1;
       } 
    } 
   return (errorLevel);
 } 

int LNadd(LNS *lna, LNS *lnb, 
          LNS *ln3) 
 { 
   int i, cnt, state = 0, carry = 0;
   LNS ln1, ln2;
 
   if (0 == lna->dc)
      *ln3 = *lnb;
   else
      if (0 == lnb->dc)
         *ln3 = *lna;
      else
       { 
         ln1 = *lna;
         ln2 = *lnb;
         if (ln1.sign != ln2.sign)
          { 
            LNnegate(&ln2);
            state = LNsubtract(&ln1, &ln2, ln3);
          } 
         else
          { 
            if (ln1.exp > ln2.exp)
             { 
               LNshift(&ln1, 1);
               LNshift(&ln2, (ln1.exp - ln2.exp));
             } 
            else
             { 
               LNshift(&ln2, 1);
               LNshift(&ln1, (ln2.exp - ln1.exp));
              } 
          
            if (ln1.dc > ln2.dc)
             { 
               for (i = ln1.dc - 1; i >= ln2.dc; i--)
                  ln3->a[i] = ln1.a[i];
               cnt = ln2.dc;
               ln3->dc = ln1.dc;
             } 
            else
             { 
               for (i = ln2.dc - 1; i >= ln1.dc; i--)
                  ln3->a[i] = ln2.a[i];
               cnt = ln1.dc;
               ln3->dc = ln2.dc;
             } 
            ln3->exp = ln1.exp;
            for (i = cnt - 1; i >= 0;  i--)
             { 
               ln3->a[i] = ln1.a[i] + ln2.a[i] + carry;
               if (ln3->a[i] > 9)
                { 
                  carry = 1;
                  ln3->a[i] -= 10;
                } 
               else
                { 
                  carry = 0;
                } 
             } 
            LNnormalize(ln3);
          } 
       } 
   return state;
 } 

int LNsubtract(LNS *lna, LNS *lnb, 
               LNS *ln3) 
 { 
   int ret = 0;
   LNS ln1, ln2;
   
   ln1 = *lna;
   ln2 = *lnb;
   
   if (0 == lna->dc)
    { 
      *ln3 = *lnb;
      LNnegate(ln3);
    } 
   else
      if (0 == lnb->dc)
         *ln3 = *lna;
      else
       { 
         if (ln1.sign != ln2.sign)
          { 
            LNnegate(&ln2);
            ret = LNadd(&ln1, &ln2, ln3);
          } 
         else
          { 
            int t, i, tmp, borrow = 0;
      
            t = LNcompare(&ln1, &ln2);
            if (0 == t)
             { 
               ln3->sign = 1;
               ln3->exp = 0;
               ln3->dc = 0;
             } 
            else
              if (0 > t)
               { 
                 ret = LNsubtract(&ln2, &ln1, ln3);
                 ln3->sign = -1 * ln3->sign;
               } 
              else
               { 
                 ln3->sign = ln1.sign;
                 ln3->exp = ln1.exp;
                 LNshift(&ln2, (ln1.exp - ln2.exp)); 
                 if (ln1.dc != ln2.dc)
                    if (ln1.dc > ln2.dc)
                     { 
                       for (i=ln2.dc; i < ln1.dc; i++)
                          ln2.a[i] = 0;
                       ln2.dc = ln1.dc;
                     } 
                    else
                     { 
                       for (i=ln1.dc; i < ln2.dc; i++)
                          ln1.a[i] = 0;
                       ln1.dc = ln2.dc;
                     } 
                
                 for (i = ln1.dc - 1; i >= 0; i--)
                  { 
                    tmp = borrow + ln2.a[i];
                    if (ln1.a[i] > tmp)
                     { 
                       ln3->a[i] = ln1.a[i] - tmp;
                       borrow = 0;
                     } 
                    else
                     { 
                       ln3->a[i] = (10 + ln1.a[i]) - tmp;
                       borrow = 1;
                     } 
                  } 
                 LNnormalize(ln3);
               } 
          } 
       } 
   return ret;
 } 

int LNmultiply(LNS *ln1, LNS *ln2, 
               LNS *ln3) 
 { 
   if ((0 == ln1->dc) || (0 == ln2->dc))
    { 
      ln3->dc = 0;
      ln3->sign = 0;
      ln3->exp = 0;
      ln3->a[0] = 0;
    } 
   else
    { 
      int i1, i2, i3, dig, tmp, carry;

      ln3->sign = ln1->sign * ln2->sign;
      ln3->exp = ln1->exp + ln2->exp;
      ln3->dc = ln1->dc + ln2->dc;
      dig = ln3->dc - 1;
      for (i3=0; i3 <= dig; i3++)
         ln3->a[i3] = 0;
      for (i2=ln2->dc - 1; i2 >= 0; i2--)
       { 
         carry = 0;
         i3 = dig--;
         for (i1=ln1->dc - 1; i1 >= 0; i1--)
          { 
            tmp = (ln1->a[i1] * ln2->a[i2]) + carry + ln3->a[i3];
            if (tmp > 9)
             { 
               carry = tmp / 10;
               ln3->a[i3] = (tmp % 10);
             } 
            else
             { 
               carry = 0;
               ln3->a[i3] = tmp;
             } 
            i3--;
          } 
         ln3->a[i3] = ln3->a[i3] + carry;
       } 
      LNnormalize(ln3);
    } 
    return 0;
 } 

int LNdivide(LNS *ln1, long int i2, LNS *ln3) 
 { 
   int i, tot = 0;

   ln3->exp = ln1->exp;
   ln3->sign = ln1->sign * ((0 < i2) ? 1 : -1);
   for (i=0; i < ln1->dc; i++)
    { 
      tot += ln1->a[i];
      if (tot >= i2)
       { 
         ln3->a[i] = tot / i2;
         tot = (tot % i2) * 10;
       } 
      else
       { 
         ln3->a[i] = 0;
         tot *= 10;
       } 
    } 

   ln3->dc = i;
   while ((LMD > ln3->dc) && (0 < tot))
    { 
      if (tot >= i2)
       { 
         ln3->a[ln3->dc] = tot / i2;
         tot = (tot % i2) * 10;
       } 
      else
       { 
         ln3->a[ln3->dc] = 0;
         tot *= 10;
       } 
      ln3->dc++;
    } 
   LNnormalize(ln3); 
   return 0;
 } 

int LNdcnvrt(double d, LNS *n) 
 { 
   char str[LMD];
    
   sprintf(str, "%ld:", d);
   return LNstr2arr(str, n);
 } 

int LNcopy(LNS *ln1, LNS *ln2) 
 { 
   int i;

   ln2->sign = ln1->sign;
   ln2->exp = ln1->exp;
   ln2->dc = ln1->dc;
   for (i=0; i < ln1->dc; i++) 
      ln2->a[i] = ln1->a[i];
   return 0;
 } 





[ Powered by Red Hat Linux ] [ Powered by Apache ] [ Powered by PHP ]

The statements and opinions included in these pages are those of only. Any statements and opinions included in these pages are not those of Louisiana State University or the LSU Board of Supervisors.
© 1999, 2000, 2001, 2002, 2003 Isaac Traxler