1 /* number.c: Implements arbitrary precision numbers. */
3 Copyright (C) 1991, 1992, 1993, 1994, 1997, 2000 Free Software Foundation, Inc.
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License , or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; see the file COPYING. If not, write to:
18 The Free Software Foundation, Inc.
19 59 Temple Place, Suite 330
20 Boston, MA 02111-1307 USA.
23 You may contact the author by:
24 e-mail: philnelson@acm.org
25 us-mail: Philip A. Nelson
26 Computer Science Department, 9062
27 Western Washington University
28 Bellingham, WA 98226-9062
30 *************************************************************************/
37 #include <ctype.h>/* Prototypes needed for external utility routines. */
39 #define bc_rt_warn rt_warn
40 #define bc_rt_error rt_error
41 #define bc_out_of_memory out_of_memory
43 _PROTOTYPE(void rt_warn
, (char *mesg
,...));
44 _PROTOTYPE(void rt_error
, (char *mesg
,...));
45 _PROTOTYPE(void out_of_memory
, (void));
47 /* Storage used for special numbers. */
52 static bc_num _bc_Free_list
= NULL
;
54 /* new_num allocates a number and sets fields to known values. */
57 bc_new_num (length
, scale
)
62 if (_bc_Free_list
!= NULL
) {
64 _bc_Free_list
= temp
->n_next
;
66 temp
= (bc_num
) malloc (sizeof(bc_struct
));
67 if (temp
== NULL
) bc_out_of_memory ();
71 temp
->n_scale
= scale
;
73 temp
->n_ptr
= (char *) malloc (length
+scale
);
74 if (temp
->n_ptr
== NULL
) bc_out_of_memory();
75 temp
->n_value
= temp
->n_ptr
;
76 memset (temp
->n_ptr
, 0, length
+scale
);
80 /* "Frees" a bc_num NUM. Actually decreases reference count and only
81 frees the storage if reference count is zero. */
87 if (*num
== NULL
) return;
89 if ((*num
)->n_refs
== 0) {
92 (*num
)->n_next
= _bc_Free_list
;
99 /* Intitialize the number package! */
104 _zero_
= bc_new_num (1,0);
105 _one_
= bc_new_num (1,0);
106 _one_
->n_value
[0] = 1;
107 _two_
= bc_new_num (1,0);
108 _two_
->n_value
[0] = 2;
112 /* Make a copy of a number! Just increments the reference count! */
123 /* Initialize a number NUM by making it a copy of zero. */
129 *num
= bc_copy_num (_zero_
);
132 /* For many things, we may have leading zeros in a number NUM.
133 _bc_rm_leading_zeros just moves the data "value" pointer to the
134 correct place and adjusts the length. */
137 _bc_rm_leading_zeros (num
)
140 /* We can move n_value to point to the first non zero digit! */
141 while (*num
->n_value
== 0 && num
->n_len
> 1) {
148 /* Compare two bc numbers. Return value is 0 if equal, -1 if N1 is less
149 than N2 and +1 if N1 is greater than N2. If USE_SIGN is false, just
150 compare the magnitudes. */
153 _bc_do_compare (n1
, n2
, use_sign
, ignore_last
)
161 /* First, compare signs. */
162 if (use_sign
&& n1
->n_sign
!= n2
->n_sign
)
164 if (n1
->n_sign
== PLUS
)
165 return (1); /* Positive N1 > Negative N2 */
167 return (-1); /* Negative N1 < Positive N1 */
170 /* Now compare the magnitude. */
171 if (n1
->n_len
!= n2
->n_len
)
173 if (n1
->n_len
> n2
->n_len
)
175 /* Magnitude of n1 > n2. */
176 if (!use_sign
|| n1
->n_sign
== PLUS
)
183 /* Magnitude of n1 < n2. */
184 if (!use_sign
|| n1
->n_sign
== PLUS
)
191 /* If we get here, they have the same number of integer digits.
192 check the integer part and the equal length part of the fraction. */
193 count
= n1
->n_len
+ MIN (n1
->n_scale
, n2
->n_scale
);
197 while ((count
> 0) && (*n1ptr
== *n2ptr
))
203 if (ignore_last
&& count
== 1 && n1
->n_scale
== n2
->n_scale
)
209 /* Magnitude of n1 > n2. */
210 if (!use_sign
|| n1
->n_sign
== PLUS
)
217 /* Magnitude of n1 < n2. */
218 if (!use_sign
|| n1
->n_sign
== PLUS
)
225 /* They are equal up to the last part of the equal part of the fraction. */
226 if (n1
->n_scale
!= n2
->n_scale
)
228 if (n1
->n_scale
> n2
->n_scale
)
230 for (count
= n1
->n_scale
-n2
->n_scale
; count
>0; count
--)
233 /* Magnitude of n1 > n2. */
234 if (!use_sign
|| n1
->n_sign
== PLUS
)
242 for (count
= n2
->n_scale
-n1
->n_scale
; count
>0; count
--)
245 /* Magnitude of n1 < n2. */
246 if (!use_sign
|| n1
->n_sign
== PLUS
)
254 /* They must be equal! */
259 /* This is the "user callable" routine to compare numbers N1 and N2. */
265 return _bc_do_compare (n1
, n2
, TRUE
, FALSE
);
268 /* In some places we need to check if the number is negative. */
274 return num
->n_sign
== MINUS
;
277 /* In some places we need to check if the number NUM is zero. */
287 if (num
== _zero_
) return TRUE
;
290 count
= num
->n_len
+ num
->n_scale
;
294 while ((count
> 0) && (*nptr
++ == 0)) count
--;
302 /* In some places we need to check if the number NUM is almost zero.
303 Specifically, all but the last digit is 0 and the last digit is 1.
304 Last digit is defined by scale. */
307 bc_is_near_zero (num
, scale
)
315 if (scale
> num
->n_scale
)
316 scale
= num
->n_scale
;
319 count
= num
->n_len
+ scale
;
323 while ((count
> 0) && (*nptr
++ == 0)) count
--;
325 if (count
!= 0 && (count
!= 1 || *--nptr
!= 1))
332 /* Perform addition: N1 is added to N2 and the value is
333 returned. The signs of N1 and N2 are ignored.
334 SCALE_MIN is to set the minimum scale of the result. */
337 _bc_do_add (n1
, n2
, scale_min
)
342 int sum_scale
, sum_digits
;
343 char *n1ptr
, *n2ptr
, *sumptr
;
344 int carry
, n1bytes
, n2bytes
;
348 sum_scale
= MAX (n1
->n_scale
, n2
->n_scale
);
349 sum_digits
= MAX (n1
->n_len
, n2
->n_len
) + 1;
350 sum
= bc_new_num (sum_digits
, MAX(sum_scale
, scale_min
));
352 /* Zero extra digits made by scale_min. */
353 if (scale_min
> sum_scale
)
355 sumptr
= (char *) (sum
->n_value
+ sum_scale
+ sum_digits
);
356 for (count
= scale_min
- sum_scale
; count
> 0; count
--)
360 /* Start with the fraction part. Initialize the pointers. */
361 n1bytes
= n1
->n_scale
;
362 n2bytes
= n2
->n_scale
;
363 n1ptr
= (char *) (n1
->n_value
+ n1
->n_len
+ n1bytes
- 1);
364 n2ptr
= (char *) (n2
->n_value
+ n2
->n_len
+ n2bytes
- 1);
365 sumptr
= (char *) (sum
->n_value
+ sum_scale
+ sum_digits
- 1);
367 /* Add the fraction part. First copy the longer fraction.*/
368 if (n1bytes
!= n2bytes
)
370 if (n1bytes
> n2bytes
)
371 while (n1bytes
>n2bytes
)
372 { *sumptr
-- = *n1ptr
--; n1bytes
--;}
374 while (n2bytes
>n1bytes
)
375 { *sumptr
-- = *n2ptr
--; n2bytes
--;}
378 /* Now add the remaining fraction part and equal size integer parts. */
379 n1bytes
+= n1
->n_len
;
380 n2bytes
+= n2
->n_len
;
382 while ((n1bytes
> 0) && (n2bytes
> 0))
384 *sumptr
= *n1ptr
-- + *n2ptr
-- + carry
;
385 if (*sumptr
> (BASE
-1))
397 /* Now add carry the longer integer part. */
399 { n1bytes
= n2bytes
; n1ptr
= n2ptr
; }
400 while (n1bytes
-- > 0)
402 *sumptr
= *n1ptr
-- + carry
;
403 if (*sumptr
> (BASE
-1))
413 /* Set final carry. */
417 /* Adjust sum and return. */
418 _bc_rm_leading_zeros (sum
);
423 /* Perform subtraction: N2 is subtracted from N1 and the value is
424 returned. The signs of N1 and N2 are ignored. Also, N1 is
425 assumed to be larger than N2. SCALE_MIN is the minimum scale
429 _bc_do_sub (n1
, n2
, scale_min
)
434 int diff_scale
, diff_len
;
435 int min_scale
, min_len
;
436 char *n1ptr
, *n2ptr
, *diffptr
;
437 int borrow
, count
, val
;
439 /* Allocate temporary storage. */
440 diff_len
= MAX (n1
->n_len
, n2
->n_len
);
441 diff_scale
= MAX (n1
->n_scale
, n2
->n_scale
);
442 min_len
= MIN (n1
->n_len
, n2
->n_len
);
443 min_scale
= MIN (n1
->n_scale
, n2
->n_scale
);
444 diff
= bc_new_num (diff_len
, MAX(diff_scale
, scale_min
));
446 /* Zero extra digits made by scale_min. */
447 if (scale_min
> diff_scale
)
449 diffptr
= (char *) (diff
->n_value
+ diff_len
+ diff_scale
);
450 for (count
= scale_min
- diff_scale
; count
> 0; count
--)
454 /* Initialize the subtract. */
455 n1ptr
= (char *) (n1
->n_value
+ n1
->n_len
+ n1
->n_scale
-1);
456 n2ptr
= (char *) (n2
->n_value
+ n2
->n_len
+ n2
->n_scale
-1);
457 diffptr
= (char *) (diff
->n_value
+ diff_len
+ diff_scale
-1);
459 /* Subtract the numbers. */
462 /* Take care of the longer scaled number. */
463 if (n1
->n_scale
!= min_scale
)
465 /* n1 has the longer scale */
466 for (count
= n1
->n_scale
- min_scale
; count
> 0; count
--)
467 *diffptr
-- = *n1ptr
--;
471 /* n2 has the longer scale */
472 for (count
= n2
->n_scale
- min_scale
; count
> 0; count
--)
474 val
= - *n2ptr
-- - borrow
;
486 /* Now do the equal length scale and integer parts. */
488 for (count
= 0; count
< min_len
+ min_scale
; count
++)
490 val
= *n1ptr
-- - *n2ptr
-- - borrow
;
501 /* If n1 has more digits then n2, we now do that subtract. */
502 if (diff_len
!= min_len
)
504 for (count
= diff_len
- min_len
; count
> 0; count
--)
506 val
= *n1ptr
-- - borrow
;
518 /* Clean up and return. */
519 _bc_rm_leading_zeros (diff
);
524 /* Here is the full subtract routine that takes care of negative numbers.
525 N2 is subtracted from N1 and the result placed in RESULT. SCALE_MIN
526 is the minimum scale for the result. */
529 bc_sub (n1
, n2
, result
, scale_min
)
530 bc_num n1
, n2
, *result
;
537 if (n1
->n_sign
!= n2
->n_sign
)
539 diff
= _bc_do_add (n1
, n2
, scale_min
);
540 diff
->n_sign
= n1
->n_sign
;
544 /* subtraction must be done. */
545 /* Compare magnitudes. */
546 cmp_res
= _bc_do_compare (n1
, n2
, FALSE
, FALSE
);
550 /* n1 is less than n2, subtract n1 from n2. */
551 diff
= _bc_do_sub (n2
, n1
, scale_min
);
552 diff
->n_sign
= (n2
->n_sign
== PLUS
? MINUS
: PLUS
);
555 /* They are equal! return zero! */
556 res_scale
= MAX (scale_min
, MAX(n1
->n_scale
, n2
->n_scale
));
557 diff
= bc_new_num (1, res_scale
);
558 memset (diff
->n_value
, 0, res_scale
+1);
561 /* n2 is less than n1, subtract n2 from n1. */
562 diff
= _bc_do_sub (n1
, n2
, scale_min
);
563 diff
->n_sign
= n1
->n_sign
;
568 /* Clean up and return. */
569 bc_free_num (result
);
574 /* Here is the full add routine that takes care of negative numbers.
575 N1 is added to N2 and the result placed into RESULT. SCALE_MIN
576 is the minimum scale for the result. */
579 bc_add (n1
, n2
, result
, scale_min
)
580 bc_num n1
, n2
, *result
;
587 if (n1
->n_sign
== n2
->n_sign
)
589 sum
= _bc_do_add (n1
, n2
, scale_min
);
590 sum
->n_sign
= n1
->n_sign
;
594 /* subtraction must be done. */
595 cmp_res
= _bc_do_compare (n1
, n2
, FALSE
, FALSE
); /* Compare magnitudes. */
599 /* n1 is less than n2, subtract n1 from n2. */
600 sum
= _bc_do_sub (n2
, n1
, scale_min
);
601 sum
->n_sign
= n2
->n_sign
;
604 /* They are equal! return zero with the correct scale! */
605 res_scale
= MAX (scale_min
, MAX(n1
->n_scale
, n2
->n_scale
));
606 sum
= bc_new_num (1, res_scale
);
607 memset (sum
->n_value
, 0, res_scale
+1);
610 /* n2 is less than n1, subtract n2 from n1. */
611 sum
= _bc_do_sub (n1
, n2
, scale_min
);
612 sum
->n_sign
= n1
->n_sign
;
616 /* Clean up and return. */
617 bc_free_num (result
);
621 /* Recursive vs non-recursive multiply crossover ranges. */
622 #if defined(MULDIGITS)
623 #include "muldigits.h"
625 #define MUL_BASE_DIGITS 80
628 int mul_base_digits
= MUL_BASE_DIGITS
;
629 #define MUL_SMALL_DIGITS mul_base_digits/4
631 /* Multiply utility routines */
634 new_sub_num (length
, scale
, value
)
640 if (_bc_Free_list
!= NULL
) {
641 temp
= _bc_Free_list
;
642 _bc_Free_list
= temp
->n_next
;
644 temp
= (bc_num
) malloc (sizeof(bc_struct
));
645 if (temp
== NULL
) bc_out_of_memory ();
648 temp
->n_len
= length
;
649 temp
->n_scale
= scale
;
652 temp
->n_value
= value
;
657 _bc_simp_mul (bc_num n1
, int n1len
, bc_num n2
, int n2len
, bc_num
*prod
,
660 char *n1ptr
, *n2ptr
, *pvptr
;
661 char *n1end
, *n2end
; /* To the end of n1 and n2. */
662 int indx
, sum
, prodlen
;
664 prodlen
= n1len
+n2len
+1;
666 *prod
= bc_new_num (prodlen
, 0);
668 n1end
= (char *) (n1
->n_value
+ n1len
- 1);
669 n2end
= (char *) (n2
->n_value
+ n2len
- 1);
670 pvptr
= (char *) ((*prod
)->n_value
+ prodlen
- 1);
673 /* Here is the loop... */
674 for (indx
= 0; indx
< prodlen
-1; indx
++)
676 n1ptr
= (char *) (n1end
- MAX(0, indx
-n2len
+1));
677 n2ptr
= (char *) (n2end
- MIN(indx
, n2len
-1));
678 while ((n1ptr
>= n1
->n_value
) && (n2ptr
<= n2end
))
679 sum
+= *n1ptr
-- * *n2ptr
++;
680 *pvptr
-- = sum
% BASE
;
687 /* A special adder/subtractor for the recursive divide and conquer
688 multiply algorithm. Note: if sub is called, accum must
689 be larger that what is being subtracted. Also, accum and val
690 must have n_scale = 0. (e.g. they must look like integers. *) */
692 _bc_shift_addsub (bc_num accum
, bc_num val
, int shift
, int sub
)
694 signed char *accp
, *valp
;
698 if (val
->n_value
[0] == 0)
700 assert (accum
->n_len
+accum
->n_scale
>= shift
+count
);
702 /* Set up pointers and others */
703 accp
= (signed char *)(accum
->n_value
+
704 accum
->n_len
+ accum
->n_scale
- shift
- 1);
705 valp
= (signed char *)(val
->n_value
+ val
->n_len
- 1);
709 /* Subtraction, carry is really borrow. */
711 *accp
-= *valp
-- + carry
;
730 *accp
+= *valp
-- + carry
;
731 if (*accp
> (BASE
-1)) {
741 if (*accp
> (BASE
-1))
749 /* Recursive divide and conquer multiply algorithm.
751 Let u = u0 + u1*(b^n)
752 Let v = v0 + v1*(b^n)
753 Then uv = (B^2n+B^n)*u1*v1 + B^n*(u1-u0)*(v0-v1) + (B^n+1)*u0*v0
755 B is the base of storage, number of digits in u1,u0 close to equal.
758 _bc_rec_mul (bc_num u
, int ulen
, bc_num v
, int vlen
, bc_num
*prod
,
761 bc_num u0
, u1
, v0
, v1
;
763 bc_num m1
, m2
, m3
, d1
, d2
;
764 int n
, prodlen
, m1zero
;
768 if ((ulen
+vlen
) < mul_base_digits
769 || ulen
< MUL_SMALL_DIGITS
770 || vlen
< MUL_SMALL_DIGITS
) {
771 _bc_simp_mul (u
, ulen
, v
, vlen
, prod
, full_scale
);
775 /* Calculate n -- the u and v split point in digits. */
776 n
= (MAX(ulen
, vlen
)+1) / 2;
780 u1
= bc_copy_num (_zero_
);
781 u0
= new_sub_num (ulen
,0, u
->n_value
);
783 u1
= new_sub_num (ulen
-n
, 0, u
->n_value
);
784 u0
= new_sub_num (n
, 0, u
->n_value
+ulen
-n
);
787 v1
= bc_copy_num (_zero_
);
788 v0
= new_sub_num (vlen
,0, v
->n_value
);
790 v1
= new_sub_num (vlen
-n
, 0, v
->n_value
);
791 v0
= new_sub_num (n
, 0, v
->n_value
+vlen
-n
);
793 _bc_rm_leading_zeros (u1
);
794 _bc_rm_leading_zeros (u0
);
796 _bc_rm_leading_zeros (v1
);
797 _bc_rm_leading_zeros (v0
);
800 m1zero
= bc_is_zero(u1
) || bc_is_zero(v1
);
802 /* Calculate sub results ... */
806 bc_sub (u1
, u0
, &d1
, 0);
808 bc_sub (v0
, v1
, &d2
, 0);
812 /* Do recursive multiplies and shifted adds. */
814 m1
= bc_copy_num (_zero_
);
816 _bc_rec_mul (u1
, u1
->n_len
, v1
, v1
->n_len
, &m1
, 0);
818 if (bc_is_zero(d1
) || bc_is_zero(d2
))
819 m2
= bc_copy_num (_zero_
);
821 _bc_rec_mul (d1
, d1len
, d2
, d2len
, &m2
, 0);
823 if (bc_is_zero(u0
) || bc_is_zero(v0
))
824 m3
= bc_copy_num (_zero_
);
826 _bc_rec_mul (u0
, u0
->n_len
, v0
, v0
->n_len
, &m3
, 0);
828 /* Initialize product */
829 prodlen
= ulen
+vlen
+1;
830 *prod
= bc_new_num(prodlen
, 0);
833 _bc_shift_addsub (*prod
, m1
, 2*n
, 0);
834 _bc_shift_addsub (*prod
, m1
, n
, 0);
836 _bc_shift_addsub (*prod
, m3
, n
, 0);
837 _bc_shift_addsub (*prod
, m3
, 0, 0);
838 _bc_shift_addsub (*prod
, m2
, n
, d1
->n_sign
!= d2
->n_sign
);
852 /* The multiply routine. N2 times N1 is put int PROD with the scale of
853 the result being MIN(N2 scale+N1 scale, MAX (SCALE, N2 scale, N1 scale)).
857 bc_multiply (n1
, n2
, prod
, scale
)
858 bc_num n1
, n2
, *prod
;
863 int full_scale
, prod_scale
;
865 /* Initialize things. */
866 len1
= n1
->n_len
+ n1
->n_scale
;
867 len2
= n2
->n_len
+ n2
->n_scale
;
868 full_scale
= n1
->n_scale
+ n2
->n_scale
;
869 prod_scale
= MIN(full_scale
,MAX(scale
,MAX(n1
->n_scale
,n2
->n_scale
)));
871 /* Do the multiply */
872 _bc_rec_mul (n1
, len1
, n2
, len2
, &pval
, full_scale
);
874 /* Assign to prod and clean up the number. */
875 pval
->n_sign
= ( n1
->n_sign
== n2
->n_sign
? PLUS
: MINUS
);
876 pval
->n_value
= pval
->n_ptr
;
877 pval
->n_len
= len2
+ len1
+ 1 - full_scale
;
878 pval
->n_scale
= prod_scale
;
879 _bc_rm_leading_zeros (pval
);
880 if (bc_is_zero (pval
))
886 /* Some utility routines for the divide: First a one digit multiply.
887 NUM (with SIZE digits) is multiplied by DIGIT and the result is
888 placed into RESULT. It is written so that NUM and RESULT can be
889 the same pointers. */
892 _one_mult (num
, size
, digit
, result
)
895 unsigned char *result
;
898 unsigned char *nptr
, *rptr
;
901 memset (result
, 0, size
);
905 memcpy (result
, num
, size
);
909 nptr
= (unsigned char *) (num
+size
-1);
910 rptr
= (unsigned char *) (result
+size
-1);
915 value
= *nptr
-- * digit
+ carry
;
916 *rptr
-- = value
% BASE
;
917 carry
= value
/ BASE
;
920 if (carry
!= 0) *rptr
= carry
;
926 /* The full division routine. This computes N1 / N2. It returns
927 0 if the division is ok and the result is in QUOT. The number of
928 digits after the decimal point is SCALE. It returns -1 if division
929 by zero is tried. The algorithm is found in Knuth Vol 2. p237. */
932 bc_divide (n1
, n2
, quot
, scale
)
933 bc_num n1
, n2
, *quot
;
937 unsigned char *num1
, *num2
;
938 unsigned char *ptr1
, *ptr2
, *n2ptr
, *qptr
;
940 unsigned int len1
, len2
, scale2
, qdigits
, extra
, count
;
941 unsigned int qdig
, qguess
, borrow
, carry
;
946 /* Test for divide by zero. */
947 if (bc_is_zero (n2
)) return -1;
949 /* Test for divide by 1. If it is we must truncate. */
950 if (n2
->n_scale
== 0)
952 if (n2
->n_len
== 1 && *n2
->n_value
== 1)
954 qval
= bc_new_num (n1
->n_len
, scale
);
955 qval
->n_sign
= (n1
->n_sign
== n2
->n_sign
? PLUS
: MINUS
);
956 memset (&qval
->n_value
[n1
->n_len
],0,scale
);
957 memcpy (qval
->n_value
, n1
->n_value
,
958 n1
->n_len
+ MIN(n1
->n_scale
,scale
));
964 /* Set up the divide. Move the decimal point on n1 by n2's scale.
965 Remember, zeros on the end of num2 are wasted effort for dividing. */
966 scale2
= n2
->n_scale
;
967 n2ptr
= (unsigned char *) n2
->n_value
+n2
->n_len
+scale2
-1;
968 while ((scale2
> 0) && (*n2ptr
-- == 0)) scale2
--;
970 len1
= n1
->n_len
+ scale2
;
971 scale1
= n1
->n_scale
- scale2
;
973 extra
= scale
- scale1
;
976 num1
= (unsigned char *) malloc (n1
->n_len
+n1
->n_scale
+extra
+2);
977 if (num1
== NULL
) bc_out_of_memory();
978 memset (num1
, 0, n1
->n_len
+n1
->n_scale
+extra
+2);
979 memcpy (num1
+1, n1
->n_value
, n1
->n_len
+n1
->n_scale
);
981 len2
= n2
->n_len
+ scale2
;
982 num2
= (unsigned char *) malloc (len2
+1);
983 if (num2
== NULL
) bc_out_of_memory();
984 memcpy (num2
, n2
->n_value
, len2
);
993 /* Calculate the number of quotient digits. */
994 if (len2
> len1
+scale
)
1003 qdigits
= scale
+1; /* One for the zero integer part. */
1005 qdigits
= len1
-len2
+scale
+1;
1008 /* Allocate and zero the storage for the quotient. */
1009 qval
= bc_new_num (qdigits
-scale
,scale
);
1010 memset (qval
->n_value
, 0, qdigits
);
1012 /* Allocate storage for the temporary storage mval. */
1013 mval
= (unsigned char *) malloc (len2
+1);
1014 if (mval
== NULL
) bc_out_of_memory ();
1016 /* Now for the full divide algorithm. */
1020 norm
= 10 / ((int)*n2ptr
+ 1);
1023 _one_mult (num1
, len1
+scale1
+extra
+1, norm
, num1
);
1024 _one_mult (n2ptr
, len2
, norm
, n2ptr
);
1027 /* Initialize divide loop. */
1030 qptr
= (unsigned char *) qval
->n_value
+len2
-len1
;
1032 qptr
= (unsigned char *) qval
->n_value
;
1035 while (qdig
<= len1
+scale
-len2
)
1037 /* Calculate the quotient digit guess. */
1038 if (*n2ptr
== num1
[qdig
])
1041 qguess
= (num1
[qdig
]*10 + num1
[qdig
+1]) / *n2ptr
;
1044 if (n2ptr
[1]*qguess
>
1045 (num1
[qdig
]*10 + num1
[qdig
+1] - *n2ptr
*qguess
)*10
1050 if (n2ptr
[1]*qguess
>
1051 (num1
[qdig
]*10 + num1
[qdig
+1] - *n2ptr
*qguess
)*10
1056 /* Multiply and subtract. */
1061 _one_mult (n2ptr
, len2
, qguess
, mval
+1);
1062 ptr1
= (unsigned char *) num1
+qdig
+len2
;
1063 ptr2
= (unsigned char *) mval
+len2
;
1064 for (count
= 0; count
< len2
+1; count
++)
1066 val
= (int) *ptr1
- (int) *ptr2
-- - borrow
;
1078 /* Test for negative result. */
1082 ptr1
= (unsigned char *) num1
+qdig
+len2
;
1083 ptr2
= (unsigned char *) n2ptr
+len2
-1;
1085 for (count
= 0; count
< len2
; count
++)
1087 val
= (int) *ptr1
+ (int) *ptr2
-- + carry
;
1097 if (carry
== 1) *ptr1
= (*ptr1
+ 1) % 10;
1100 /* We now know the quotient digit. */
1106 /* Clean up and return the number. */
1107 qval
->n_sign
= ( n1
->n_sign
== n2
->n_sign
? PLUS
: MINUS
);
1108 if (bc_is_zero (qval
)) qval
->n_sign
= PLUS
;
1109 _bc_rm_leading_zeros (qval
);
1113 /* Clean up temporary storage. */
1118 return 0; /* Everything is OK. */
1122 /* Division *and* modulo for numbers. This computes both NUM1 / NUM2 and
1123 NUM1 % NUM2 and puts the results in QUOT and REM, except that if QUOT
1124 is NULL then that store will be omitted.
1128 bc_divmod (num1
, num2
, quot
, rem
, scale
)
1129 bc_num num1
, num2
, *quot
, *rem
;
1132 bc_num quotient
= NULL
;
1136 /* Check for correct numbers. */
1137 if (bc_is_zero (num2
)) return -1;
1139 /* Calculate final scale. */
1140 rscale
= MAX (num1
->n_scale
, num2
->n_scale
+scale
);
1144 bc_divide (num1
, num2
, &temp
, scale
);
1146 quotient
= bc_copy_num (temp
);
1147 bc_multiply (temp
, num2
, &temp
, rscale
);
1148 bc_sub (num1
, temp
, rem
, rscale
);
1149 bc_free_num (&temp
);
1157 return 0; /* Everything is OK. */
1161 /* Modulo for numbers. This computes NUM1 % NUM2 and puts the
1162 result in RESULT. */
1165 bc_modulo (num1
, num2
, result
, scale
)
1166 bc_num num1
, num2
, *result
;
1169 return bc_divmod (num1
, num2
, NULL
, result
, scale
);
1172 /* Raise BASE to the EXPO power, reduced modulo MOD. The result is
1173 placed in RESULT. If a EXPO is not an integer,
1174 only the integer part is used. */
1177 bc_raisemod (base
, expo
, mod
, result
, scale
)
1178 bc_num base
, expo
, mod
, *result
;
1181 bc_num power
, exponent
, parity
, temp
;
1184 /* Check for correct numbers. */
1185 if (bc_is_zero(mod
)) return -1;
1186 if (bc_is_neg(expo
)) return -1;
1188 /* Set initial values. */
1189 power
= bc_copy_num (base
);
1190 exponent
= bc_copy_num (expo
);
1191 temp
= bc_copy_num (_one_
);
1192 bc_init_num(&parity
);
1194 /* Check the base for scale digits. */
1195 if (base
->n_scale
!= 0)
1196 bc_rt_warn ("non-zero scale in base");
1198 /* Check the exponent for scale digits. */
1199 if (exponent
->n_scale
!= 0)
1201 bc_rt_warn ("non-zero scale in exponent");
1202 bc_divide (exponent
, _one_
, &exponent
, 0); /*truncate */
1205 /* Check the modulus for scale digits. */
1206 if (mod
->n_scale
!= 0)
1207 bc_rt_warn ("non-zero scale in modulus");
1209 /* Do the calculation. */
1210 rscale
= MAX(scale
, base
->n_scale
);
1211 while ( !bc_is_zero(exponent
) )
1213 (void) bc_divmod (exponent
, _two_
, &exponent
, &parity
, 0);
1214 if ( !bc_is_zero(parity
) )
1216 bc_multiply (temp
, power
, &temp
, rscale
);
1217 (void) bc_modulo (temp
, mod
, &temp
, scale
);
1220 bc_multiply (power
, power
, &power
, rscale
);
1221 (void) bc_modulo (power
, mod
, &power
, scale
);
1224 /* Assign the value. */
1225 bc_free_num (&power
);
1226 bc_free_num (&exponent
);
1227 bc_free_num (result
);
1229 return 0; /* Everything is OK. */
1232 /* Raise NUM1 to the NUM2 power. The result is placed in RESULT.
1233 Maximum exponent is LONG_MAX. If a NUM2 is not an integer,
1234 only the integer part is used. */
1237 bc_raise (num1
, num2
, result
, scale
)
1238 bc_num num1
, num2
, *result
;
1248 /* Check the exponent for scale digits and convert to a long. */
1249 if (num2
->n_scale
!= 0)
1250 bc_rt_warn ("non-zero scale in exponent");
1251 exponent
= bc_num2long (num2
);
1252 if (exponent
== 0 && (num2
->n_len
> 1 || num2
->n_value
[0] != 0))
1253 bc_rt_error ("exponent too large in raise");
1255 /* Special case if exponent is a zero. */
1258 bc_free_num (result
);
1259 *result
= bc_copy_num (_one_
);
1263 /* Other initializations. */
1267 exponent
= -exponent
;
1273 rscale
= MIN (num1
->n_scale
*exponent
, MAX(scale
, num1
->n_scale
));
1276 /* Set initial value of temp. */
1277 power
= bc_copy_num (num1
);
1278 pwrscale
= num1
->n_scale
;
1279 while ((exponent
& 1) == 0)
1281 pwrscale
= 2*pwrscale
;
1282 bc_multiply (power
, power
, &power
, pwrscale
);
1283 exponent
= exponent
>> 1;
1285 temp
= bc_copy_num (power
);
1286 calcscale
= pwrscale
;
1287 exponent
= exponent
>> 1;
1289 /* Do the calculation. */
1290 while (exponent
> 0)
1292 pwrscale
= 2*pwrscale
;
1293 bc_multiply (power
, power
, &power
, pwrscale
);
1294 if ((exponent
& 1) == 1) {
1295 calcscale
= pwrscale
+ calcscale
;
1296 bc_multiply (temp
, power
, &temp
, calcscale
);
1298 exponent
= exponent
>> 1;
1301 /* Assign the value. */
1304 bc_divide (_one_
, temp
, result
, rscale
);
1305 bc_free_num (&temp
);
1309 bc_free_num (result
);
1311 if ((*result
)->n_scale
> rscale
)
1312 (*result
)->n_scale
= rscale
;
1314 bc_free_num (&power
);
1317 /* Take the square root NUM and return it in NUM with SCALE digits
1318 after the decimal place. */
1321 bc_sqrt (num
, scale
)
1325 int rscale
, cmp_res
, done
;
1327 bc_num guess
, guess1
, point5
, diff
;
1329 /* Initial checks. */
1330 cmp_res
= bc_compare (*num
, _zero_
);
1332 return 0; /* error */
1338 *num
= bc_copy_num (_zero_
);
1342 cmp_res
= bc_compare (*num
, _one_
);
1346 *num
= bc_copy_num (_one_
);
1350 /* Initialize the variables. */
1351 rscale
= MAX (scale
, (*num
)->n_scale
);
1352 bc_init_num(&guess
);
1353 bc_init_num(&guess1
);
1355 point5
= bc_new_num (1,1);
1356 point5
->n_value
[1] = 5;
1359 /* Calculate the initial guess. */
1362 /* The number is between 0 and 1. Guess should start at 1. */
1363 guess
= bc_copy_num (_one_
);
1364 cscale
= (*num
)->n_scale
;
1368 /* The number is greater than 1. Guess should start at 10^(exp/2). */
1369 bc_int2num (&guess
,10);
1371 bc_int2num (&guess1
,(*num
)->n_len
);
1372 bc_multiply (guess1
, point5
, &guess1
, 0);
1373 guess1
->n_scale
= 0;
1374 bc_raise (guess
, guess1
, &guess
, 0);
1375 bc_free_num (&guess1
);
1379 /* Find the square root using Newton's algorithm. */
1383 bc_free_num (&guess1
);
1384 guess1
= bc_copy_num (guess
);
1385 bc_divide (*num
, guess
, &guess
, cscale
);
1386 bc_add (guess
, guess1
, &guess
, 0);
1387 bc_multiply (guess
, point5
, &guess
, cscale
);
1388 bc_sub (guess
, guess1
, &diff
, cscale
+1);
1389 if (bc_is_near_zero (diff
, cscale
))
1391 if (cscale
< rscale
+1)
1392 cscale
= MIN (cscale
*3, rscale
+1);
1398 /* Assign the number and clean up. */
1400 bc_divide (guess
,_one_
,num
,rscale
);
1401 bc_free_num (&guess
);
1402 bc_free_num (&guess1
);
1403 bc_free_num (&point5
);
1404 bc_free_num (&diff
);
1409 /* The following routines provide output for bcd numbers package
1410 using the rules of POSIX bc for output. */
1412 /* This structure is used for saving digits in the conversion process. */
1413 typedef struct stk_rec
{
1415 struct stk_rec
*next
;
1418 /* The reference string for digits. */
1419 static char ref_str
[] = "0123456789ABCDEF";
1422 /* A special output routine for "multi-character digits." Exactly
1423 SIZE characters must be output for the value VAL. If SPACE is
1424 non-zero, we must output one space before the number. OUT_CHAR
1425 is the actual routine for writing the characters. */
1428 bc_out_long (val
, size
, space
, out_char
)
1432 void (*out_char
)(int);
1440 if (space
) (*out_char
) (' ');
1441 sprintf (digits
, "%ld", val
);
1442 len
= strlen (digits
);
1448 for (ix
=0; ix
< len
; ix
++)
1449 (*out_char
) (digits
[ix
]);
1452 /* Output of a bcd number. NUM is written in base O_BASE using OUT_CHAR
1453 as the routine to do the actual output of the characters. */
1456 bc_out_num (num
, o_base
, out_char
, leading_zero
)
1460 void (*out_char
)(int);
1467 int index
, fdigit
, pre_space
;
1468 stk_rec
*digits
, *temp
;
1469 bc_num int_part
, frac_part
, base
, cur_dig
, t_num
, max_o_digit
;
1471 /* The negative sign if needed. */
1472 if (num
->n_sign
== MINUS
) (*out_char
) ('-');
1474 /* Output the number. */
1475 if (bc_is_zero (num
))
1480 /* The number is in base 10, do it the fast way. */
1481 nptr
= num
->n_value
;
1482 if (num
->n_len
> 1 || *nptr
!= 0)
1483 for (index
=num
->n_len
; index
>0; index
--)
1484 (*out_char
) (BCD_CHAR(*nptr
++));
1488 if (leading_zero
&& bc_is_zero (num
))
1491 /* Now the fraction. */
1492 if (num
->n_scale
> 0)
1495 for (index
=0; index
<num
->n_scale
; index
++)
1496 (*out_char
) (BCD_CHAR(*nptr
++));
1501 /* special case ... */
1502 if (leading_zero
&& bc_is_zero (num
))
1505 /* The number is some other base. */
1507 bc_init_num (&int_part
);
1508 bc_divide (num
, _one_
, &int_part
, 0);
1509 bc_init_num (&frac_part
);
1510 bc_init_num (&cur_dig
);
1511 bc_init_num (&base
);
1512 bc_sub (num
, int_part
, &frac_part
, 0);
1513 /* Make the INT_PART and FRAC_PART positive. */
1514 int_part
->n_sign
= PLUS
;
1515 frac_part
->n_sign
= PLUS
;
1516 bc_int2num (&base
, o_base
);
1517 bc_init_num (&max_o_digit
);
1518 bc_int2num (&max_o_digit
, o_base
-1);
1521 /* Get the digits of the integer part and push them on a stack. */
1522 while (!bc_is_zero (int_part
))
1524 bc_modulo (int_part
, base
, &cur_dig
, 0);
1525 temp
= (stk_rec
*) malloc (sizeof(stk_rec
));
1526 if (temp
== NULL
) bc_out_of_memory();
1527 temp
->digit
= bc_num2long (cur_dig
);
1528 temp
->next
= digits
;
1530 bc_divide (int_part
, base
, &int_part
, 0);
1533 /* Print the digits on the stack. */
1536 /* Output the digits. */
1537 while (digits
!= NULL
)
1540 digits
= digits
->next
;
1542 (*out_char
) (ref_str
[ (int) temp
->digit
]);
1544 bc_out_long (temp
->digit
, max_o_digit
->n_len
, 1, out_char
);
1549 /* Get and print the digits of the fraction part. */
1550 if (num
->n_scale
> 0)
1554 t_num
= bc_copy_num (_one_
);
1555 while (t_num
->n_len
<= num
->n_scale
) {
1556 bc_multiply (frac_part
, base
, &frac_part
, num
->n_scale
);
1557 fdigit
= bc_num2long (frac_part
);
1558 bc_int2num (&int_part
, fdigit
);
1559 bc_sub (frac_part
, int_part
, &frac_part
, 0);
1561 (*out_char
) (ref_str
[fdigit
]);
1563 bc_out_long (fdigit
, max_o_digit
->n_len
, pre_space
, out_char
);
1566 bc_multiply (t_num
, base
, &t_num
, 0);
1568 bc_free_num (&t_num
);
1572 bc_free_num (&int_part
);
1573 bc_free_num (&frac_part
);
1574 bc_free_num (&base
);
1575 bc_free_num (&cur_dig
);
1576 bc_free_num (&max_o_digit
);
1579 /* Convert a number NUM to a long. The function returns only the integer
1580 part of the number. For numbers that are too large to represent as
1581 a long, this function returns a zero. This can be detected by checking
1582 the NUM for zero after having a zero returned. */
1592 /* Extract the int value, ignore the fraction. */
1594 nptr
= num
->n_value
;
1595 for (index
=num
->n_len
; (index
>0) && (val
<=(LONG_MAX
/BASE
)); index
--)
1596 val
= val
*BASE
+ *nptr
++;
1598 /* Check for overflow. If overflow, return zero. */
1599 if (index
>0) val
= 0;
1600 if (val
< 0) val
= 0;
1602 /* Return the value. */
1603 if (num
->n_sign
== PLUS
)
1610 /* Convert an integer VAL to a bc number NUM. */
1613 bc_int2num (num
, val
)
1629 /* Get things going. */
1631 *bptr
++ = val
% BASE
;
1634 /* Extract remaining digits. */
1637 *bptr
++ = val
% BASE
;
1639 ix
++; /* Count the digits. */
1642 /* Make the number. */
1644 *num
= bc_new_num (ix
, 0);
1645 if (neg
) (*num
)->n_sign
= MINUS
;
1647 /* Assign the digits. */
1648 vptr
= (*num
)->n_value
;
1653 /* Convert a numbers to a string. Base 10 only.*/
1663 /* Allocate the string memory. */
1664 signch
= ( num
->n_sign
== PLUS
? 0 : 1 ); /* Number of sign chars. */
1665 if (num
->n_scale
> 0)
1666 str
= (char *) malloc (num
->n_len
+ num
->n_scale
+ 2 + signch
);
1668 str
= (char *) malloc (num
->n_len
+ 1 + signch
);
1669 if (str
== NULL
) bc_out_of_memory();
1671 /* The negative sign if needed. */
1673 if (signch
) *sptr
++ = '-';
1675 /* Load the whole number. */
1676 nptr
= num
->n_value
;
1677 for (index
=num
->n_len
; index
>0; index
--)
1678 *sptr
++ = BCD_CHAR(*nptr
++);
1680 /* Now the fraction. */
1681 if (num
->n_scale
> 0)
1684 for (index
=0; index
<num
->n_scale
; index
++)
1685 *sptr
++ = BCD_CHAR(*nptr
++);
1688 /* Terminate the string and return it! */
1692 /* Convert strings to bc numbers. Base 10 only.*/
1695 bc_str2num (num
, str
, scale
)
1700 int digits
, strscale
;
1707 /* Check for valid number and count digits. */
1712 if ( (*ptr
== '+') || (*ptr
== '-')) ptr
++; /* Sign */
1713 while (*ptr
== '0') ptr
++; /* Skip leading zeros. */
1714 while (isdigit((int)*ptr
)) ptr
++, digits
++; /* digits */
1715 if (*ptr
== '.') ptr
++; /* decimal point */
1716 while (isdigit((int)*ptr
)) ptr
++, strscale
++; /* digits */
1717 if ((*ptr
!= '\0') || (digits
+strscale
== 0))
1719 *num
= bc_copy_num (_zero_
);
1723 /* Adjust numbers and allocate storage and initialize fields. */
1724 strscale
= MIN(strscale
, scale
);
1730 *num
= bc_new_num (digits
, strscale
);
1732 /* Build the whole number. */
1736 (*num
)->n_sign
= MINUS
;
1741 (*num
)->n_sign
= PLUS
;
1742 if (*ptr
== '+') ptr
++;
1744 while (*ptr
== '0') ptr
++; /* Skip leading zeros. */
1745 nptr
= (*num
)->n_value
;
1751 for (;digits
> 0; digits
--)
1752 *nptr
++ = CH_VAL(*ptr
++);
1755 /* Build the fractional part. */
1758 ptr
++; /* skip the decimal point! */
1759 for (;strscale
> 0; strscale
--)
1760 *nptr
++ = CH_VAL(*ptr
++);
1764 /* pn prints the number NUM in base 10. */
1777 bc_out_num (num
, 10, out_char
, 0);
1782 /* pv prints a character array as if it was a string of bcd digits. */
1790 printf ("%s=", name
);
1791 for (i
=0; i
<len
; i
++) printf ("%c",BCD_CHAR(num
[i
]));