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]));