123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230 |
- #include <config.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <ctype.h>
- #include <stdarg.h>
- #include "bcmath.h"
- #include "private.h"
- bc_num
- _bc_do_add (n1, n2, scale_min)
- bc_num n1, n2;
- int scale_min;
- {
- bc_num sum;
- int sum_scale, sum_digits;
- char *n1ptr, *n2ptr, *sumptr;
- int carry, n1bytes, n2bytes;
- int count;
-
- sum_scale = MAX (n1->n_scale, n2->n_scale);
- sum_digits = MAX (n1->n_len, n2->n_len) + 1;
- sum = bc_new_num (sum_digits, MAX(sum_scale, scale_min));
-
- if (scale_min > sum_scale)
- {
- sumptr = (char *) (sum->n_value + sum_scale + sum_digits);
- for (count = scale_min - sum_scale; count > 0; count--)
- *sumptr++ = 0;
- }
-
- n1bytes = n1->n_scale;
- n2bytes = n2->n_scale;
- n1ptr = (char *) (n1->n_value + n1->n_len + n1bytes - 1);
- n2ptr = (char *) (n2->n_value + n2->n_len + n2bytes - 1);
- sumptr = (char *) (sum->n_value + sum_scale + sum_digits - 1);
-
- if (n1bytes != n2bytes)
- {
- if (n1bytes > n2bytes)
- while (n1bytes>n2bytes)
- { *sumptr-- = *n1ptr--; n1bytes--;}
- else
- while (n2bytes>n1bytes)
- { *sumptr-- = *n2ptr--; n2bytes--;}
- }
-
- n1bytes += n1->n_len;
- n2bytes += n2->n_len;
- carry = 0;
- while ((n1bytes > 0) && (n2bytes > 0))
- {
- *sumptr = *n1ptr-- + *n2ptr-- + carry;
- if (*sumptr > (BASE-1))
- {
- carry = 1;
- *sumptr -= BASE;
- }
- else
- carry = 0;
- sumptr--;
- n1bytes--;
- n2bytes--;
- }
-
- if (n1bytes == 0)
- { n1bytes = n2bytes; n1ptr = n2ptr; }
- while (n1bytes-- > 0)
- {
- *sumptr = *n1ptr-- + carry;
- if (*sumptr > (BASE-1))
- {
- carry = 1;
- *sumptr -= BASE;
- }
- else
- carry = 0;
- sumptr--;
- }
-
- if (carry == 1)
- *sumptr += 1;
-
- _bc_rm_leading_zeros (sum);
- return sum;
- }
- bc_num
- _bc_do_sub (n1, n2, scale_min)
- bc_num n1, n2;
- int scale_min;
- {
- bc_num diff;
- int diff_scale, diff_len;
- int min_scale, min_len;
- char *n1ptr, *n2ptr, *diffptr;
- int borrow, count, val;
-
- diff_len = MAX (n1->n_len, n2->n_len);
- diff_scale = MAX (n1->n_scale, n2->n_scale);
- min_len = MIN (n1->n_len, n2->n_len);
- min_scale = MIN (n1->n_scale, n2->n_scale);
- diff = bc_new_num (diff_len, MAX(diff_scale, scale_min));
-
- if (scale_min > diff_scale)
- {
- diffptr = (char *) (diff->n_value + diff_len + diff_scale);
- for (count = scale_min - diff_scale; count > 0; count--)
- *diffptr++ = 0;
- }
-
- n1ptr = (char *) (n1->n_value + n1->n_len + n1->n_scale -1);
- n2ptr = (char *) (n2->n_value + n2->n_len + n2->n_scale -1);
- diffptr = (char *) (diff->n_value + diff_len + diff_scale -1);
-
- borrow = 0;
-
- if (n1->n_scale != min_scale)
- {
-
- for (count = n1->n_scale - min_scale; count > 0; count--)
- *diffptr-- = *n1ptr--;
- }
- else
- {
-
- for (count = n2->n_scale - min_scale; count > 0; count--)
- {
- val = - *n2ptr-- - borrow;
- if (val < 0)
- {
- val += BASE;
- borrow = 1;
- }
- else
- borrow = 0;
- *diffptr-- = val;
- }
- }
-
- for (count = 0; count < min_len + min_scale; count++)
- {
- val = *n1ptr-- - *n2ptr-- - borrow;
- if (val < 0)
- {
- val += BASE;
- borrow = 1;
- }
- else
- borrow = 0;
- *diffptr-- = val;
- }
-
- if (diff_len != min_len)
- {
- for (count = diff_len - min_len; count > 0; count--)
- {
- val = *n1ptr-- - borrow;
- if (val < 0)
- {
- val += BASE;
- borrow = 1;
- }
- else
- borrow = 0;
- *diffptr-- = val;
- }
- }
-
- _bc_rm_leading_zeros (diff);
- return diff;
- }
|