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