|
41 | 41 | bc_num _bc_do_add(bc_num n1, bc_num n2, size_t scale_min)
|
42 | 42 | {
|
43 | 43 | bc_num sum;
|
44 |
| - size_t sum_scale, sum_digits; |
| 44 | + size_t sum_len = MAX(n1->n_len, n2->n_len) + 1; |
| 45 | + size_t sum_scale = MAX(n1->n_scale, n2->n_scale); |
| 46 | + size_t min_len = MIN (n1->n_len, n2->n_len); |
| 47 | + size_t min_scale = MIN(n1->n_scale, n2->n_scale); |
| 48 | + size_t min_bytes = min_len + min_scale; |
45 | 49 | char *n1ptr, *n2ptr, *sumptr;
|
46 |
| - size_t n1bytes, n2bytes; |
47 |
| - bool carry; |
| 50 | + bool carry = 0; |
| 51 | + size_t count; |
48 | 52 |
|
49 | 53 | /* Prepare sum. */
|
50 |
| - sum_scale = MAX (n1->n_scale, n2->n_scale); |
51 |
| - sum_digits = MAX (n1->n_len, n2->n_len) + 1; |
52 |
| - sum = bc_new_num (sum_digits, MAX(sum_scale, scale_min)); |
| 54 | + sum = bc_new_num (sum_len, MAX(sum_scale, scale_min)); |
53 | 55 |
|
54 | 56 | /* Start with the fraction part. Initialize the pointers. */
|
55 |
| - n1bytes = n1->n_scale; |
56 |
| - n2bytes = n2->n_scale; |
57 |
| - n1ptr = (char *) (n1->n_value + n1->n_len + n1bytes - 1); |
58 |
| - n2ptr = (char *) (n2->n_value + n2->n_len + n2bytes - 1); |
59 |
| - sumptr = (char *) (sum->n_value + sum_scale + sum_digits - 1); |
| 57 | + n1ptr = (char *) (n1->n_value + n1->n_len + n1->n_scale - 1); |
| 58 | + n2ptr = (char *) (n2->n_value + n2->n_len + n2->n_scale - 1); |
| 59 | + sumptr = (char *) (sum->n_value + sum_scale + sum_len - 1); |
60 | 60 |
|
61 | 61 | /* Add the fraction part. First copy the longer fraction.*/
|
62 |
| - if (n1bytes != n2bytes) { |
63 |
| - if (n1bytes > n2bytes) { |
64 |
| - while (n1bytes > n2bytes) { |
65 |
| - *sumptr-- = *n1ptr--; |
66 |
| - n1bytes--; |
67 |
| - } |
68 |
| - } else { |
69 |
| - while (n2bytes > n1bytes) { |
70 |
| - *sumptr-- = *n2ptr--; |
71 |
| - n2bytes--; |
72 |
| - } |
| 62 | + if (n1->n_scale != min_scale) { |
| 63 | + /* n1 has the longer scale */ |
| 64 | + for (count = n1->n_scale - min_scale; count > 0; count--) { |
| 65 | + *sumptr-- = *n1ptr--; |
| 66 | + } |
| 67 | + } else { |
| 68 | + /* n2 has the longer scale */ |
| 69 | + for (count = n2->n_scale - min_scale; count > 0; count--) { |
| 70 | + *sumptr-- = *n2ptr--; |
73 | 71 | }
|
74 | 72 | }
|
75 | 73 |
|
76 | 74 | /* Now add the remaining fraction part and equal size integer parts. */
|
77 |
| - n1bytes += n1->n_len; |
78 |
| - n2bytes += n2->n_len; |
79 |
| - carry = 0; |
80 |
| - while ((n1bytes > 0) && (n2bytes > 0)) { |
| 75 | + for (count = 0; count < min_bytes; count++) { |
81 | 76 | *sumptr = *n1ptr-- + *n2ptr-- + carry;
|
82 |
| - if (*sumptr > (BASE - 1)) { |
83 |
| - carry = 1; |
| 77 | + if (*sumptr >= BASE) { |
84 | 78 | *sumptr -= BASE;
|
| 79 | + carry = 1; |
85 | 80 | } else {
|
86 | 81 | carry = 0;
|
87 | 82 | }
|
88 | 83 | sumptr--;
|
89 |
| - n1bytes--; |
90 |
| - n2bytes--; |
91 | 84 | }
|
92 | 85 |
|
93 | 86 | /* Now add carry the longer integer part. */
|
94 |
| - if (n1bytes == 0) { |
95 |
| - n1bytes = n2bytes; |
96 |
| - n1ptr = n2ptr; |
97 |
| - } |
98 |
| - while (n1bytes-- > 0) { |
99 |
| - *sumptr = *n1ptr-- + carry; |
100 |
| - if (*sumptr > (BASE - 1)) { |
101 |
| - carry = true; |
102 |
| - *sumptr -= BASE; |
103 |
| - } else { |
104 |
| - carry = false; |
| 87 | + if (sum_len != min_len) { |
| 88 | + if (n2->n_len > n1->n_len) { |
| 89 | + n1ptr = n2ptr; |
| 90 | + } |
| 91 | + for (count = sum_len - min_len; count > 0; count--) { |
| 92 | + *sumptr = *n1ptr-- + carry; |
| 93 | + if (*sumptr >= BASE) { |
| 94 | + *sumptr -= BASE; |
| 95 | + carry = 1; |
| 96 | + } else { |
| 97 | + carry = 0; |
| 98 | + } |
| 99 | + sumptr--; |
105 | 100 | }
|
106 |
| - sumptr--; |
107 | 101 | }
|
108 | 102 |
|
109 | 103 | /* Set final carry. */
|
110 |
| - if (carry) { |
111 |
| - *sumptr += 1; |
112 |
| - } |
| 104 | + *sumptr += carry; |
113 | 105 |
|
114 | 106 | /* Adjust sum and return. */
|
115 | 107 | _bc_rm_leading_zeros(sum);
|
|
0 commit comments