1 /*
2 * *****************************************************************************
3 *
4 * SPDX-License-Identifier: BSD-2-Clause
5 *
6 * Copyright (c) 2018-2023 Gavin D. Howard and contributors.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions are met:
10 *
11 * * Redistributions of source code must retain the above copyright notice, this
12 * list of conditions and the following disclaimer.
13 *
14 * * Redistributions in binary form must reproduce the above copyright notice,
15 * this list of conditions and the following disclaimer in the documentation
16 * and/or other materials provided with the distribution.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
22 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28 * POSSIBILITY OF SUCH DAMAGE.
29 *
30 * *****************************************************************************
31 *
32 * Code for the number type.
33 *
34 */
35
36 #include <assert.h>
37 #include <ctype.h>
38 #include <stdbool.h>
39 #include <stdlib.h>
40 #include <string.h>
41 #include <setjmp.h>
42 #include <limits.h>
43
44 #include <num.h>
45 #include <rand.h>
46 #include <vm.h>
47 #if BC_ENABLE_LIBRARY
48 #include <library.h>
49 #endif // BC_ENABLE_LIBRARY
50
51 // Before you try to understand this code, see the development manual
52 // (manuals/development.md#numbers).
53
54 static void
55 bc_num_m(BcNum* a, BcNum* b, BcNum* restrict c, size_t scale);
56
57 /**
58 * Multiply two numbers and throw a math error if they overflow.
59 * @param a The first operand.
60 * @param b The second operand.
61 * @return The product of the two operands.
62 */
63 static inline size_t
bc_num_mulOverflow(size_t a,size_t b)64 bc_num_mulOverflow(size_t a, size_t b)
65 {
66 size_t res = a * b;
67 if (BC_ERR(BC_VM_MUL_OVERFLOW(a, b, res))) bc_err(BC_ERR_MATH_OVERFLOW);
68 return res;
69 }
70
71 /**
72 * Conditionally negate @a n based on @a neg. Algorithm taken from
73 * https://graphics.stanford.edu/~seander/bithacks.html#ConditionalNegate .
74 * @param n The value to turn into a signed value and negate.
75 * @param neg The condition to negate or not.
76 */
77 static inline ssize_t
bc_num_neg(size_t n,bool neg)78 bc_num_neg(size_t n, bool neg)
79 {
80 return (((ssize_t) n) ^ -((ssize_t) neg)) + neg;
81 }
82
83 /**
84 * Compare a BcNum against zero.
85 * @param n The number to compare.
86 * @return -1 if the number is less than 0, 1 if greater, and 0 if equal.
87 */
88 ssize_t
bc_num_cmpZero(const BcNum * n)89 bc_num_cmpZero(const BcNum* n)
90 {
91 return bc_num_neg((n)->len != 0, BC_NUM_NEG(n));
92 }
93
94 /**
95 * Return the number of integer limbs in a BcNum. This is the opposite of rdx.
96 * @param n The number to return the amount of integer limbs for.
97 * @return The amount of integer limbs in @a n.
98 */
99 static inline size_t
bc_num_int(const BcNum * n)100 bc_num_int(const BcNum* n)
101 {
102 return n->len ? n->len - BC_NUM_RDX_VAL(n) : 0;
103 }
104
105 /**
106 * Expand a number's allocation capacity to at least req limbs.
107 * @param n The number to expand.
108 * @param req The number limbs to expand the allocation capacity to.
109 */
110 static void
bc_num_expand(BcNum * restrict n,size_t req)111 bc_num_expand(BcNum* restrict n, size_t req)
112 {
113 assert(n != NULL);
114
115 req = req >= BC_NUM_DEF_SIZE ? req : BC_NUM_DEF_SIZE;
116
117 if (req > n->cap)
118 {
119 BC_SIG_LOCK;
120
121 n->num = bc_vm_realloc(n->num, BC_NUM_SIZE(req));
122 n->cap = req;
123
124 BC_SIG_UNLOCK;
125 }
126 }
127
128 /**
129 * Set a number to 0 with the specified scale.
130 * @param n The number to set to zero.
131 * @param scale The scale to set the number to.
132 */
133 static inline void
bc_num_setToZero(BcNum * restrict n,size_t scale)134 bc_num_setToZero(BcNum* restrict n, size_t scale)
135 {
136 assert(n != NULL);
137 n->scale = scale;
138 n->len = n->rdx = 0;
139 }
140
141 void
bc_num_zero(BcNum * restrict n)142 bc_num_zero(BcNum* restrict n)
143 {
144 bc_num_setToZero(n, 0);
145 }
146
147 void
bc_num_one(BcNum * restrict n)148 bc_num_one(BcNum* restrict n)
149 {
150 bc_num_zero(n);
151 n->len = 1;
152 n->num[0] = 1;
153 }
154
155 /**
156 * "Cleans" a number, which means reducing the length if the most significant
157 * limbs are zero.
158 * @param n The number to clean.
159 */
160 static void
bc_num_clean(BcNum * restrict n)161 bc_num_clean(BcNum* restrict n)
162 {
163 // Reduce the length.
164 while (BC_NUM_NONZERO(n) && !n->num[n->len - 1])
165 {
166 n->len -= 1;
167 }
168
169 // Special cases.
170 if (BC_NUM_ZERO(n)) n->rdx = 0;
171 else
172 {
173 // len must be at least as much as rdx.
174 size_t rdx = BC_NUM_RDX_VAL(n);
175 if (n->len < rdx) n->len = rdx;
176 }
177 }
178
179 /**
180 * Returns the log base 10 of @a i. I could have done this with floating-point
181 * math, and in fact, I originally did. However, that was the only
182 * floating-point code in the entire codebase, and I decided I didn't want any.
183 * This is fast enough. Also, it might handle larger numbers better.
184 * @param i The number to return the log base 10 of.
185 * @return The log base 10 of @a i.
186 */
187 static size_t
bc_num_log10(size_t i)188 bc_num_log10(size_t i)
189 {
190 size_t len;
191
192 for (len = 1; i; i /= BC_BASE, ++len)
193 {
194 continue;
195 }
196
197 assert(len - 1 <= BC_BASE_DIGS + 1);
198
199 return len - 1;
200 }
201
202 /**
203 * Returns the number of decimal digits in a limb that are zero starting at the
204 * most significant digits. This basically returns how much of the limb is used.
205 * @param n The number.
206 * @return The number of decimal digits that are 0 starting at the most
207 * significant digits.
208 */
209 static inline size_t
bc_num_zeroDigits(const BcDig * n)210 bc_num_zeroDigits(const BcDig* n)
211 {
212 assert(*n >= 0);
213 assert(((size_t) *n) < BC_BASE_POW);
214 return BC_BASE_DIGS - bc_num_log10((size_t) *n);
215 }
216
217 /**
218 * Return the total number of integer digits in a number. This is the opposite
219 * of scale, like bc_num_int() is the opposite of rdx.
220 * @param n The number.
221 * @return The number of integer digits in @a n.
222 */
223 static size_t
bc_num_intDigits(const BcNum * n)224 bc_num_intDigits(const BcNum* n)
225 {
226 size_t digits = bc_num_int(n) * BC_BASE_DIGS;
227 if (digits > 0) digits -= bc_num_zeroDigits(n->num + n->len - 1);
228 return digits;
229 }
230
231 /**
232 * Returns the number of limbs of a number that are non-zero starting at the
233 * most significant limbs. This expects that there are *no* integer limbs in the
234 * number because it is specifically to figure out how many zero limbs after the
235 * decimal place to ignore. If there are zero limbs after non-zero limbs, they
236 * are counted as non-zero limbs.
237 * @param n The number.
238 * @return The number of non-zero limbs after the decimal point.
239 */
240 static size_t
bc_num_nonZeroLen(const BcNum * restrict n)241 bc_num_nonZeroLen(const BcNum* restrict n)
242 {
243 size_t i, len = n->len;
244
245 assert(len == BC_NUM_RDX_VAL(n));
246
247 for (i = len - 1; i < len && !n->num[i]; --i)
248 {
249 continue;
250 }
251
252 assert(i + 1 > 0);
253
254 return i + 1;
255 }
256
257 /**
258 * Performs a one-limb add with a carry.
259 * @param a The first limb.
260 * @param b The second limb.
261 * @param carry An in/out parameter; the carry in from the previous add and the
262 * carry out from this add.
263 * @return The resulting limb sum.
264 */
265 static BcDig
bc_num_addDigits(BcDig a,BcDig b,bool * carry)266 bc_num_addDigits(BcDig a, BcDig b, bool* carry)
267 {
268 assert(((BcBigDig) BC_BASE_POW) * 2 == ((BcDig) BC_BASE_POW) * 2);
269 assert(a < BC_BASE_POW && a >= 0);
270 assert(b < BC_BASE_POW && b >= 0);
271
272 a += b + *carry;
273 *carry = (a >= BC_BASE_POW);
274 if (*carry) a -= BC_BASE_POW;
275
276 assert(a >= 0);
277 assert(a < BC_BASE_POW);
278
279 return a;
280 }
281
282 /**
283 * Performs a one-limb subtract with a carry.
284 * @param a The first limb.
285 * @param b The second limb.
286 * @param carry An in/out parameter; the carry in from the previous subtract
287 * and the carry out from this subtract.
288 * @return The resulting limb difference.
289 */
290 static BcDig
bc_num_subDigits(BcDig a,BcDig b,bool * carry)291 bc_num_subDigits(BcDig a, BcDig b, bool* carry)
292 {
293 assert(a < BC_BASE_POW && a >= 0);
294 assert(b < BC_BASE_POW && b >= 0);
295
296 b += *carry;
297 *carry = (a < b);
298 if (*carry) a += BC_BASE_POW;
299
300 assert(a - b >= 0);
301 assert(a - b < BC_BASE_POW);
302
303 return a - b;
304 }
305
306 /**
307 * Add two BcDig arrays and store the result in the first array.
308 * @param a The first operand and out array.
309 * @param b The second operand.
310 * @param len The length of @a b.
311 */
312 static void
bc_num_addArrays(BcDig * restrict a,const BcDig * restrict b,size_t len)313 bc_num_addArrays(BcDig* restrict a, const BcDig* restrict b, size_t len)
314 {
315 size_t i;
316 bool carry = false;
317
318 for (i = 0; i < len; ++i)
319 {
320 a[i] = bc_num_addDigits(a[i], b[i], &carry);
321 }
322
323 // Take care of the extra limbs in the bigger array.
324 for (; carry; ++i)
325 {
326 a[i] = bc_num_addDigits(a[i], 0, &carry);
327 }
328 }
329
330 /**
331 * Subtract two BcDig arrays and store the result in the first array.
332 * @param a The first operand and out array.
333 * @param b The second operand.
334 * @param len The length of @a b.
335 */
336 static void
bc_num_subArrays(BcDig * restrict a,const BcDig * restrict b,size_t len)337 bc_num_subArrays(BcDig* restrict a, const BcDig* restrict b, size_t len)
338 {
339 size_t i;
340 bool carry = false;
341
342 for (i = 0; i < len; ++i)
343 {
344 a[i] = bc_num_subDigits(a[i], b[i], &carry);
345 }
346
347 // Take care of the extra limbs in the bigger array.
348 for (; carry; ++i)
349 {
350 a[i] = bc_num_subDigits(a[i], 0, &carry);
351 }
352 }
353
354 /**
355 * Multiply a BcNum array by a one-limb number. This is a faster version of
356 * multiplication for when we can use it.
357 * @param a The BcNum to multiply by the one-limb number.
358 * @param b The one limb of the one-limb number.
359 * @param c The return parameter.
360 */
361 static void
bc_num_mulArray(const BcNum * restrict a,BcBigDig b,BcNum * restrict c)362 bc_num_mulArray(const BcNum* restrict a, BcBigDig b, BcNum* restrict c)
363 {
364 size_t i;
365 BcBigDig carry = 0;
366
367 assert(b <= BC_BASE_POW);
368
369 // Make sure the return parameter is big enough.
370 if (a->len + 1 > c->cap) bc_num_expand(c, a->len + 1);
371
372 // We want the entire return parameter to be zero for cleaning later.
373 // NOLINTNEXTLINE
374 memset(c->num, 0, BC_NUM_SIZE(c->cap));
375
376 // Actual multiplication loop.
377 for (i = 0; i < a->len; ++i)
378 {
379 BcBigDig in = ((BcBigDig) a->num[i]) * b + carry;
380 c->num[i] = in % BC_BASE_POW;
381 carry = in / BC_BASE_POW;
382 }
383
384 assert(carry < BC_BASE_POW);
385
386 // Finishing touches.
387 c->num[i] = (BcDig) carry;
388 assert(c->num[i] >= 0 && c->num[i] < BC_BASE_POW);
389 c->len = a->len;
390 c->len += (carry != 0);
391
392 bc_num_clean(c);
393
394 // Postconditions.
395 assert(!BC_NUM_NEG(c) || BC_NUM_NONZERO(c));
396 assert(BC_NUM_RDX_VAL(c) <= c->len || !c->len);
397 assert(!c->len || c->num[c->len - 1] || BC_NUM_RDX_VAL(c) == c->len);
398 }
399
400 /**
401 * Divide a BcNum array by a one-limb number. This is a faster version of divide
402 * for when we can use it.
403 * @param a The BcNum to multiply by the one-limb number.
404 * @param b The one limb of the one-limb number.
405 * @param c The return parameter for the quotient.
406 * @param rem The return parameter for the remainder.
407 */
408 static void
bc_num_divArray(const BcNum * restrict a,BcBigDig b,BcNum * restrict c,BcBigDig * rem)409 bc_num_divArray(const BcNum* restrict a, BcBigDig b, BcNum* restrict c,
410 BcBigDig* rem)
411 {
412 size_t i;
413 BcBigDig carry = 0;
414
415 assert(c->cap >= a->len);
416
417 // Actual division loop.
418 for (i = a->len - 1; i < a->len; --i)
419 {
420 BcBigDig in = ((BcBigDig) a->num[i]) + carry * BC_BASE_POW;
421 assert(in / b < BC_BASE_POW);
422 c->num[i] = (BcDig) (in / b);
423 assert(c->num[i] >= 0 && c->num[i] < BC_BASE_POW);
424 carry = in % b;
425 }
426
427 // Finishing touches.
428 c->len = a->len;
429 bc_num_clean(c);
430 *rem = carry;
431
432 // Postconditions.
433 assert(!BC_NUM_NEG(c) || BC_NUM_NONZERO(c));
434 assert(BC_NUM_RDX_VAL(c) <= c->len || !c->len);
435 assert(!c->len || c->num[c->len - 1] || BC_NUM_RDX_VAL(c) == c->len);
436 }
437
438 /**
439 * Compare two BcDig arrays and return >0 if @a b is greater, <0 if @a b is
440 * less, and 0 if equal. Both @a a and @a b must have the same length.
441 * @param a The first array.
442 * @param b The second array.
443 * @param len The minimum length of the arrays.
444 */
445 static ssize_t
bc_num_compare(const BcDig * restrict a,const BcDig * restrict b,size_t len)446 bc_num_compare(const BcDig* restrict a, const BcDig* restrict b, size_t len)
447 {
448 size_t i;
449 BcDig c = 0;
450 for (i = len - 1; i < len && !(c = a[i] - b[i]); --i)
451 {
452 continue;
453 }
454 return bc_num_neg(i + 1, c < 0);
455 }
456
457 ssize_t
bc_num_cmp(const BcNum * a,const BcNum * b)458 bc_num_cmp(const BcNum* a, const BcNum* b)
459 {
460 size_t i, min, a_int, b_int, diff, ardx, brdx;
461 BcDig* max_num;
462 BcDig* min_num;
463 bool a_max, neg = false;
464 ssize_t cmp;
465
466 assert(a != NULL && b != NULL);
467
468 // Same num? Equal.
469 if (a == b) return 0;
470
471 // Easy cases.
472 if (BC_NUM_ZERO(a)) return bc_num_neg(b->len != 0, !BC_NUM_NEG(b));
473 if (BC_NUM_ZERO(b)) return bc_num_cmpZero(a);
474 if (BC_NUM_NEG(a))
475 {
476 if (BC_NUM_NEG(b)) neg = true;
477 else return -1;
478 }
479 else if (BC_NUM_NEG(b)) return 1;
480
481 // Get the number of int limbs in each number and get the difference.
482 a_int = bc_num_int(a);
483 b_int = bc_num_int(b);
484 a_int -= b_int;
485
486 // If there's a difference, then just return the comparison.
487 if (a_int) return neg ? -((ssize_t) a_int) : (ssize_t) a_int;
488
489 // Get the rdx's and figure out the max.
490 ardx = BC_NUM_RDX_VAL(a);
491 brdx = BC_NUM_RDX_VAL(b);
492 a_max = (ardx > brdx);
493
494 // Set variables based on the above.
495 if (a_max)
496 {
497 min = brdx;
498 diff = ardx - brdx;
499 max_num = a->num + diff;
500 min_num = b->num;
501 }
502 else
503 {
504 min = ardx;
505 diff = brdx - ardx;
506 max_num = b->num + diff;
507 min_num = a->num;
508 }
509
510 // Do a full limb-by-limb comparison.
511 cmp = bc_num_compare(max_num, min_num, b_int + min);
512
513 // If we found a difference, return it based on state.
514 if (cmp) return bc_num_neg((size_t) cmp, !a_max == !neg);
515
516 // If there was no difference, then the final step is to check which number
517 // has greater or lesser limbs beyond the other's.
518 for (max_num -= diff, i = diff - 1; i < diff; --i)
519 {
520 if (max_num[i]) return bc_num_neg(1, !a_max == !neg);
521 }
522
523 return 0;
524 }
525
526 void
bc_num_truncate(BcNum * restrict n,size_t places)527 bc_num_truncate(BcNum* restrict n, size_t places)
528 {
529 size_t nrdx, places_rdx;
530
531 if (!places) return;
532
533 // Grab these needed values; places_rdx is the rdx equivalent to places like
534 // rdx is to scale.
535 nrdx = BC_NUM_RDX_VAL(n);
536 places_rdx = nrdx ? nrdx - BC_NUM_RDX(n->scale - places) : 0;
537
538 // We cannot truncate more places than we have.
539 assert(places <= n->scale && (BC_NUM_ZERO(n) || places_rdx <= n->len));
540
541 n->scale -= places;
542 BC_NUM_RDX_SET(n, nrdx - places_rdx);
543
544 // Only when the number is nonzero do we need to do the hard stuff.
545 if (BC_NUM_NONZERO(n))
546 {
547 size_t pow;
548
549 // This calculates how many decimal digits are in the least significant
550 // limb.
551 pow = n->scale % BC_BASE_DIGS;
552 pow = pow ? BC_BASE_DIGS - pow : 0;
553 pow = bc_num_pow10[pow];
554
555 n->len -= places_rdx;
556
557 // We have to move limbs to maintain invariants. The limbs must begin at
558 // the beginning of the BcNum array.
559 // NOLINTNEXTLINE
560 memmove(n->num, n->num + places_rdx, BC_NUM_SIZE(n->len));
561
562 // Clear the lower part of the last digit.
563 if (BC_NUM_NONZERO(n)) n->num[0] -= n->num[0] % (BcDig) pow;
564
565 bc_num_clean(n);
566 }
567 }
568
569 void
bc_num_extend(BcNum * restrict n,size_t places)570 bc_num_extend(BcNum* restrict n, size_t places)
571 {
572 size_t nrdx, places_rdx;
573
574 if (!places) return;
575
576 // Easy case with zero; set the scale.
577 if (BC_NUM_ZERO(n))
578 {
579 n->scale += places;
580 return;
581 }
582
583 // Grab these needed values; places_rdx is the rdx equivalent to places like
584 // rdx is to scale.
585 nrdx = BC_NUM_RDX_VAL(n);
586 places_rdx = BC_NUM_RDX(places + n->scale) - nrdx;
587
588 // This is the hard case. We need to expand the number, move the limbs, and
589 // set the limbs that were just cleared.
590 if (places_rdx)
591 {
592 bc_num_expand(n, bc_vm_growSize(n->len, places_rdx));
593 // NOLINTNEXTLINE
594 memmove(n->num + places_rdx, n->num, BC_NUM_SIZE(n->len));
595 // NOLINTNEXTLINE
596 memset(n->num, 0, BC_NUM_SIZE(places_rdx));
597 }
598
599 // Finally, set scale and rdx.
600 BC_NUM_RDX_SET(n, nrdx + places_rdx);
601 n->scale += places;
602 n->len += places_rdx;
603
604 assert(BC_NUM_RDX_VAL(n) == BC_NUM_RDX(n->scale));
605 }
606
607 /**
608 * Retires (finishes) a multiplication or division operation.
609 */
610 static void
bc_num_retireMul(BcNum * restrict n,size_t scale,bool neg1,bool neg2)611 bc_num_retireMul(BcNum* restrict n, size_t scale, bool neg1, bool neg2)
612 {
613 // Make sure scale is correct.
614 if (n->scale < scale) bc_num_extend(n, scale - n->scale);
615 else bc_num_truncate(n, n->scale - scale);
616
617 bc_num_clean(n);
618
619 // We need to ensure rdx is correct.
620 if (BC_NUM_NONZERO(n)) n->rdx = BC_NUM_NEG_VAL(n, !neg1 != !neg2);
621 }
622
623 /**
624 * Splits a number into two BcNum's. This is used in Karatsuba.
625 * @param n The number to split.
626 * @param idx The index to split at.
627 * @param a An out parameter; the low part of @a n.
628 * @param b An out parameter; the high part of @a n.
629 */
630 static void
bc_num_split(const BcNum * restrict n,size_t idx,BcNum * restrict a,BcNum * restrict b)631 bc_num_split(const BcNum* restrict n, size_t idx, BcNum* restrict a,
632 BcNum* restrict b)
633 {
634 // We want a and b to be clear.
635 assert(BC_NUM_ZERO(a));
636 assert(BC_NUM_ZERO(b));
637
638 // The usual case.
639 if (idx < n->len)
640 {
641 // Set the fields first.
642 b->len = n->len - idx;
643 a->len = idx;
644 a->scale = b->scale = 0;
645 BC_NUM_RDX_SET(a, 0);
646 BC_NUM_RDX_SET(b, 0);
647
648 assert(a->cap >= a->len);
649 assert(b->cap >= b->len);
650
651 // Copy the arrays. This is not necessary for safety, but it is faster,
652 // for some reason.
653 // NOLINTNEXTLINE
654 memcpy(b->num, n->num + idx, BC_NUM_SIZE(b->len));
655 // NOLINTNEXTLINE
656 memcpy(a->num, n->num, BC_NUM_SIZE(idx));
657
658 bc_num_clean(b);
659 }
660 // If the index is weird, just skip the split.
661 else bc_num_copy(a, n);
662
663 bc_num_clean(a);
664 }
665
666 /**
667 * Copies a number into another, but shifts the rdx so that the result number
668 * only sees the integer part of the source number.
669 * @param n The number to copy.
670 * @param r The result number with a shifted rdx, len, and num.
671 */
672 static void
bc_num_shiftRdx(const BcNum * restrict n,BcNum * restrict r)673 bc_num_shiftRdx(const BcNum* restrict n, BcNum* restrict r)
674 {
675 size_t rdx = BC_NUM_RDX_VAL(n);
676
677 r->len = n->len - rdx;
678 r->cap = n->cap - rdx;
679 r->num = n->num + rdx;
680
681 BC_NUM_RDX_SET_NEG(r, 0, BC_NUM_NEG(n));
682 r->scale = 0;
683 }
684
685 /**
686 * Shifts a number so that all of the least significant limbs of the number are
687 * skipped. This must be undone by bc_num_unshiftZero().
688 * @param n The number to shift.
689 */
690 static size_t
bc_num_shiftZero(BcNum * restrict n)691 bc_num_shiftZero(BcNum* restrict n)
692 {
693 // This is volatile to quiet a GCC warning about longjmp() clobbering.
694 volatile size_t i;
695
696 // If we don't have an integer, that is a problem, but it's also a bug
697 // because the caller should have set everything up right.
698 assert(!BC_NUM_RDX_VAL(n) || BC_NUM_ZERO(n));
699
700 for (i = 0; i < n->len && !n->num[i]; ++i)
701 {
702 continue;
703 }
704
705 n->len -= i;
706 n->num += i;
707
708 return i;
709 }
710
711 /**
712 * Undo the damage done by bc_num_unshiftZero(). This must be called like all
713 * cleanup functions: after a label used by setjmp() and longjmp().
714 * @param n The number to unshift.
715 * @param places_rdx The amount the number was originally shift.
716 */
717 static void
bc_num_unshiftZero(BcNum * restrict n,size_t places_rdx)718 bc_num_unshiftZero(BcNum* restrict n, size_t places_rdx)
719 {
720 n->len += places_rdx;
721 n->num -= places_rdx;
722 }
723
724 /**
725 * Shifts the digits right within a number by no more than BC_BASE_DIGS - 1.
726 * This is the final step on shifting numbers with the shift operators. It
727 * depends on the caller to shift the limbs properly because all it does is
728 * ensure that the rdx point is realigned to be between limbs.
729 * @param n The number to shift digits in.
730 * @param dig The number of places to shift right.
731 */
732 static void
bc_num_shift(BcNum * restrict n,BcBigDig dig)733 bc_num_shift(BcNum* restrict n, BcBigDig dig)
734 {
735 size_t i, len = n->len;
736 BcBigDig carry = 0, pow;
737 BcDig* ptr = n->num;
738
739 assert(dig < BC_BASE_DIGS);
740
741 // Figure out the parameters for division.
742 pow = bc_num_pow10[dig];
743 dig = bc_num_pow10[BC_BASE_DIGS - dig];
744
745 // Run a series of divisions and mods with carries across the entire number
746 // array. This effectively shifts everything over.
747 for (i = len - 1; i < len; --i)
748 {
749 BcBigDig in, temp;
750 in = ((BcBigDig) ptr[i]);
751 temp = carry * dig;
752 carry = in % pow;
753 ptr[i] = ((BcDig) (in / pow)) + (BcDig) temp;
754 assert(ptr[i] >= 0 && ptr[i] < BC_BASE_POW);
755 }
756
757 assert(!carry);
758 }
759
760 /**
761 * Shift a number left by a certain number of places. This is the workhorse of
762 * the left shift operator.
763 * @param n The number to shift left.
764 * @param places The amount of places to shift @a n left by.
765 */
766 static void
bc_num_shiftLeft(BcNum * restrict n,size_t places)767 bc_num_shiftLeft(BcNum* restrict n, size_t places)
768 {
769 BcBigDig dig;
770 size_t places_rdx;
771 bool shift;
772
773 if (!places) return;
774
775 // Make sure to grow the number if necessary.
776 if (places > n->scale)
777 {
778 size_t size = bc_vm_growSize(BC_NUM_RDX(places - n->scale), n->len);
779 if (size > SIZE_MAX - 1) bc_err(BC_ERR_MATH_OVERFLOW);
780 }
781
782 // If zero, we can just set the scale and bail.
783 if (BC_NUM_ZERO(n))
784 {
785 if (n->scale >= places) n->scale -= places;
786 else n->scale = 0;
787 return;
788 }
789
790 // When I changed bc to have multiple digits per limb, this was the hardest
791 // code to change. This and shift right. Make sure you understand this
792 // before attempting anything.
793
794 // This is how many limbs we will shift.
795 dig = (BcBigDig) (places % BC_BASE_DIGS);
796 shift = (dig != 0);
797
798 // Convert places to a rdx value.
799 places_rdx = BC_NUM_RDX(places);
800
801 // If the number is not an integer, we need special care. The reason an
802 // integer doesn't is because left shift would only extend the integer,
803 // whereas a non-integer might have its fractional part eliminated or only
804 // partially eliminated.
805 if (n->scale)
806 {
807 size_t nrdx = BC_NUM_RDX_VAL(n);
808
809 // If the number's rdx is bigger, that's the hard case.
810 if (nrdx >= places_rdx)
811 {
812 size_t mod = n->scale % BC_BASE_DIGS, revdig;
813
814 // We want mod to be in the range [1, BC_BASE_DIGS], not
815 // [0, BC_BASE_DIGS).
816 mod = mod ? mod : BC_BASE_DIGS;
817
818 // We need to reverse dig to get the actual number of digits.
819 revdig = dig ? BC_BASE_DIGS - dig : 0;
820
821 // If the two overflow BC_BASE_DIGS, we need to move an extra place.
822 if (mod + revdig > BC_BASE_DIGS) places_rdx = 1;
823 else places_rdx = 0;
824 }
825 else places_rdx -= nrdx;
826 }
827
828 // If this is non-zero, we need an extra place, so expand, move, and set.
829 if (places_rdx)
830 {
831 bc_num_expand(n, bc_vm_growSize(n->len, places_rdx));
832 // NOLINTNEXTLINE
833 memmove(n->num + places_rdx, n->num, BC_NUM_SIZE(n->len));
834 // NOLINTNEXTLINE
835 memset(n->num, 0, BC_NUM_SIZE(places_rdx));
836 n->len += places_rdx;
837 }
838
839 // Set the scale appropriately.
840 if (places > n->scale)
841 {
842 n->scale = 0;
843 BC_NUM_RDX_SET(n, 0);
844 }
845 else
846 {
847 n->scale -= places;
848 BC_NUM_RDX_SET(n, BC_NUM_RDX(n->scale));
849 }
850
851 // Finally, shift within limbs.
852 if (shift) bc_num_shift(n, BC_BASE_DIGS - dig);
853
854 bc_num_clean(n);
855 }
856
857 void
bc_num_shiftRight(BcNum * restrict n,size_t places)858 bc_num_shiftRight(BcNum* restrict n, size_t places)
859 {
860 BcBigDig dig;
861 size_t places_rdx, scale, scale_mod, int_len, expand;
862 bool shift;
863
864 if (!places) return;
865
866 // If zero, we can just set the scale and bail.
867 if (BC_NUM_ZERO(n))
868 {
869 n->scale += places;
870 bc_num_expand(n, BC_NUM_RDX(n->scale));
871 return;
872 }
873
874 // Amount within a limb we have to shift by.
875 dig = (BcBigDig) (places % BC_BASE_DIGS);
876 shift = (dig != 0);
877
878 scale = n->scale;
879
880 // Figure out how the scale is affected.
881 scale_mod = scale % BC_BASE_DIGS;
882 scale_mod = scale_mod ? scale_mod : BC_BASE_DIGS;
883
884 // We need to know the int length and rdx for places.
885 int_len = bc_num_int(n);
886 places_rdx = BC_NUM_RDX(places);
887
888 // If we are going to shift past a limb boundary or not, set accordingly.
889 if (scale_mod + dig > BC_BASE_DIGS)
890 {
891 expand = places_rdx - 1;
892 places_rdx = 1;
893 }
894 else
895 {
896 expand = places_rdx;
897 places_rdx = 0;
898 }
899
900 // Clamp expanding.
901 if (expand > int_len) expand -= int_len;
902 else expand = 0;
903
904 // Extend, expand, and zero.
905 bc_num_extend(n, places_rdx * BC_BASE_DIGS);
906 bc_num_expand(n, bc_vm_growSize(expand, n->len));
907 // NOLINTNEXTLINE
908 memset(n->num + n->len, 0, BC_NUM_SIZE(expand));
909
910 // Set the fields.
911 n->len += expand;
912 n->scale = 0;
913 BC_NUM_RDX_SET(n, 0);
914
915 // Finally, shift within limbs.
916 if (shift) bc_num_shift(n, dig);
917
918 n->scale = scale + places;
919 BC_NUM_RDX_SET(n, BC_NUM_RDX(n->scale));
920
921 bc_num_clean(n);
922
923 assert(BC_NUM_RDX_VAL(n) <= n->len && n->len <= n->cap);
924 assert(BC_NUM_RDX_VAL(n) == BC_NUM_RDX(n->scale));
925 }
926
927 /**
928 * Tests if a number is a integer with scale or not. Returns true if the number
929 * is not an integer. If it is, its integer shifted form is copied into the
930 * result parameter for use where only integers are allowed.
931 * @param n The integer to test and shift.
932 * @param r The number to store the shifted result into. This number should
933 * *not* be allocated.
934 * @return True if the number is a non-integer, false otherwise.
935 */
936 static bool
bc_num_nonInt(const BcNum * restrict n,BcNum * restrict r)937 bc_num_nonInt(const BcNum* restrict n, BcNum* restrict r)
938 {
939 bool zero;
940 size_t i, rdx = BC_NUM_RDX_VAL(n);
941
942 if (!rdx)
943 {
944 // NOLINTNEXTLINE
945 memcpy(r, n, sizeof(BcNum));
946 return false;
947 }
948
949 zero = true;
950
951 for (i = 0; zero && i < rdx; ++i)
952 {
953 zero = (n->num[i] == 0);
954 }
955
956 if (BC_ERR(!zero)) return true;
957
958 bc_num_shiftRdx(n, r);
959
960 return false;
961 }
962
963 #if BC_ENABLE_EXTRA_MATH
964
965 /**
966 * Execute common code for an operater that needs an integer for the second
967 * operand and return the integer operand as a BcBigDig.
968 * @param a The first operand.
969 * @param b The second operand.
970 * @param c The result operand.
971 * @return The second operand as a hardware integer.
972 */
973 static BcBigDig
bc_num_intop(const BcNum * a,const BcNum * b,BcNum * restrict c)974 bc_num_intop(const BcNum* a, const BcNum* b, BcNum* restrict c)
975 {
976 BcNum temp;
977
978 #if BC_GCC
979 temp.len = 0;
980 temp.rdx = 0;
981 temp.num = NULL;
982 #endif // BC_GCC
983
984 if (BC_ERR(bc_num_nonInt(b, &temp))) bc_err(BC_ERR_MATH_NON_INTEGER);
985
986 bc_num_copy(c, a);
987
988 return bc_num_bigdig(&temp);
989 }
990 #endif // BC_ENABLE_EXTRA_MATH
991
992 /**
993 * This is the actual implementation of add *and* subtract. Since this function
994 * doesn't need to use scale (per the bc spec), I am hijacking it to say whether
995 * it's doing an add or a subtract. And then I convert substraction to addition
996 * of negative second operand. This is a BcNumBinOp function.
997 * @param a The first operand.
998 * @param b The second operand.
999 * @param c The return parameter.
1000 * @param sub Non-zero for a subtract, zero for an add.
1001 */
1002 static void
bc_num_as(BcNum * a,BcNum * b,BcNum * restrict c,size_t sub)1003 bc_num_as(BcNum* a, BcNum* b, BcNum* restrict c, size_t sub)
1004 {
1005 BcDig* ptr_c;
1006 BcDig* ptr_l;
1007 BcDig* ptr_r;
1008 size_t i, min_rdx, max_rdx, diff, a_int, b_int, min_len, max_len, max_int;
1009 size_t len_l, len_r, ardx, brdx;
1010 bool b_neg, do_sub, do_rev_sub, carry, c_neg;
1011
1012 if (BC_NUM_ZERO(b))
1013 {
1014 bc_num_copy(c, a);
1015 return;
1016 }
1017
1018 if (BC_NUM_ZERO(a))
1019 {
1020 bc_num_copy(c, b);
1021 c->rdx = BC_NUM_NEG_VAL(c, BC_NUM_NEG(b) != sub);
1022 return;
1023 }
1024
1025 // Invert sign of b if it is to be subtracted. This operation must
1026 // precede the tests for any of the operands being zero.
1027 b_neg = (BC_NUM_NEG(b) != sub);
1028
1029 // Figure out if we will actually add the numbers if their signs are equal
1030 // or subtract.
1031 do_sub = (BC_NUM_NEG(a) != b_neg);
1032
1033 a_int = bc_num_int(a);
1034 b_int = bc_num_int(b);
1035 max_int = BC_MAX(a_int, b_int);
1036
1037 // Figure out which number will have its last limbs copied (for addition) or
1038 // subtracted (for subtraction).
1039 ardx = BC_NUM_RDX_VAL(a);
1040 brdx = BC_NUM_RDX_VAL(b);
1041 min_rdx = BC_MIN(ardx, brdx);
1042 max_rdx = BC_MAX(ardx, brdx);
1043 diff = max_rdx - min_rdx;
1044
1045 max_len = max_int + max_rdx;
1046
1047 if (do_sub)
1048 {
1049 // Check whether b has to be subtracted from a or a from b.
1050 if (a_int != b_int) do_rev_sub = (a_int < b_int);
1051 else if (ardx > brdx)
1052 {
1053 do_rev_sub = (bc_num_compare(a->num + diff, b->num, b->len) < 0);
1054 }
1055 else do_rev_sub = (bc_num_compare(a->num, b->num + diff, a->len) <= 0);
1056 }
1057 else
1058 {
1059 // The result array of the addition might come out one element
1060 // longer than the bigger of the operand arrays.
1061 max_len += 1;
1062 do_rev_sub = (a_int < b_int);
1063 }
1064
1065 assert(max_len <= c->cap);
1066
1067 // Cache values for simple code later.
1068 if (do_rev_sub)
1069 {
1070 ptr_l = b->num;
1071 ptr_r = a->num;
1072 len_l = b->len;
1073 len_r = a->len;
1074 }
1075 else
1076 {
1077 ptr_l = a->num;
1078 ptr_r = b->num;
1079 len_l = a->len;
1080 len_r = b->len;
1081 }
1082
1083 ptr_c = c->num;
1084 carry = false;
1085
1086 // This is true if the numbers have a different number of limbs after the
1087 // decimal point.
1088 if (diff)
1089 {
1090 // If the rdx values of the operands do not match, the result will
1091 // have low end elements that are the positive or negative trailing
1092 // elements of the operand with higher rdx value.
1093 if ((ardx > brdx) != do_rev_sub)
1094 {
1095 // !do_rev_sub && ardx > brdx || do_rev_sub && brdx > ardx
1096 // The left operand has BcDig values that need to be copied,
1097 // either from a or from b (in case of a reversed subtraction).
1098 // NOLINTNEXTLINE
1099 memcpy(ptr_c, ptr_l, BC_NUM_SIZE(diff));
1100 ptr_l += diff;
1101 len_l -= diff;
1102 }
1103 else
1104 {
1105 // The right operand has BcDig values that need to be copied
1106 // or subtracted from zero (in case of a subtraction).
1107 if (do_sub)
1108 {
1109 // do_sub (do_rev_sub && ardx > brdx ||
1110 // !do_rev_sub && brdx > ardx)
1111 for (i = 0; i < diff; i++)
1112 {
1113 ptr_c[i] = bc_num_subDigits(0, ptr_r[i], &carry);
1114 }
1115 }
1116 else
1117 {
1118 // !do_sub && brdx > ardx
1119 // NOLINTNEXTLINE
1120 memcpy(ptr_c, ptr_r, BC_NUM_SIZE(diff));
1121 }
1122
1123 // Future code needs to ignore the limbs we just did.
1124 ptr_r += diff;
1125 len_r -= diff;
1126 }
1127
1128 // The return value pointer needs to ignore what we just did.
1129 ptr_c += diff;
1130 }
1131
1132 // This is the length that can be directly added/subtracted.
1133 min_len = BC_MIN(len_l, len_r);
1134
1135 // After dealing with possible low array elements that depend on only one
1136 // operand above, the actual add or subtract can be performed as if the rdx
1137 // of both operands was the same.
1138 //
1139 // Inlining takes care of eliminating constant zero arguments to
1140 // addDigit/subDigit (checked in disassembly of resulting bc binary
1141 // compiled with gcc and clang).
1142 if (do_sub)
1143 {
1144 // Actual subtraction.
1145 for (i = 0; i < min_len; ++i)
1146 {
1147 ptr_c[i] = bc_num_subDigits(ptr_l[i], ptr_r[i], &carry);
1148 }
1149
1150 // Finishing the limbs beyond the direct subtraction.
1151 for (; i < len_l; ++i)
1152 {
1153 ptr_c[i] = bc_num_subDigits(ptr_l[i], 0, &carry);
1154 }
1155 }
1156 else
1157 {
1158 // Actual addition.
1159 for (i = 0; i < min_len; ++i)
1160 {
1161 ptr_c[i] = bc_num_addDigits(ptr_l[i], ptr_r[i], &carry);
1162 }
1163
1164 // Finishing the limbs beyond the direct addition.
1165 for (; i < len_l; ++i)
1166 {
1167 ptr_c[i] = bc_num_addDigits(ptr_l[i], 0, &carry);
1168 }
1169
1170 // Addition can create an extra limb. We take care of that here.
1171 ptr_c[i] = bc_num_addDigits(0, 0, &carry);
1172 }
1173
1174 assert(carry == false);
1175
1176 // The result has the same sign as a, unless the operation was a
1177 // reverse subtraction (b - a).
1178 c_neg = BC_NUM_NEG(a) != (do_sub && do_rev_sub);
1179 BC_NUM_RDX_SET_NEG(c, max_rdx, c_neg);
1180 c->len = max_len;
1181 c->scale = BC_MAX(a->scale, b->scale);
1182
1183 bc_num_clean(c);
1184 }
1185
1186 /**
1187 * The simple multiplication that karatsuba dishes out to when the length of the
1188 * numbers gets low enough. This doesn't use scale because it treats the
1189 * operands as though they are integers.
1190 * @param a The first operand.
1191 * @param b The second operand.
1192 * @param c The return parameter.
1193 */
1194 static void
bc_num_m_simp(const BcNum * a,const BcNum * b,BcNum * restrict c)1195 bc_num_m_simp(const BcNum* a, const BcNum* b, BcNum* restrict c)
1196 {
1197 size_t i, alen = a->len, blen = b->len, clen;
1198 BcDig* ptr_a = a->num;
1199 BcDig* ptr_b = b->num;
1200 BcDig* ptr_c;
1201 BcBigDig sum = 0, carry = 0;
1202
1203 assert(sizeof(sum) >= sizeof(BcDig) * 2);
1204 assert(!BC_NUM_RDX_VAL(a) && !BC_NUM_RDX_VAL(b));
1205
1206 // Make sure c is big enough.
1207 clen = bc_vm_growSize(alen, blen);
1208 bc_num_expand(c, bc_vm_growSize(clen, 1));
1209
1210 // If we don't memset, then we might have uninitialized data use later.
1211 ptr_c = c->num;
1212 // NOLINTNEXTLINE
1213 memset(ptr_c, 0, BC_NUM_SIZE(c->cap));
1214
1215 // This is the actual multiplication loop. It uses the lattice form of long
1216 // multiplication (see the explanation on the web page at
1217 // https://knilt.arcc.albany.edu/What_is_Lattice_Multiplication or the
1218 // explanation at Wikipedia).
1219 for (i = 0; i < clen; ++i)
1220 {
1221 ssize_t sidx = (ssize_t) (i - blen + 1);
1222 size_t j, k;
1223
1224 // These are the start indices.
1225 j = (size_t) BC_MAX(0, sidx);
1226 k = BC_MIN(i, blen - 1);
1227
1228 // On every iteration of this loop, a multiplication happens, then the
1229 // sum is automatically calculated.
1230 for (; j < alen && k < blen; ++j, --k)
1231 {
1232 sum += ((BcBigDig) ptr_a[j]) * ((BcBigDig) ptr_b[k]);
1233
1234 if (sum >= ((BcBigDig) BC_BASE_POW) * BC_BASE_POW)
1235 {
1236 carry += sum / BC_BASE_POW;
1237 sum %= BC_BASE_POW;
1238 }
1239 }
1240
1241 // Calculate the carry.
1242 if (sum >= BC_BASE_POW)
1243 {
1244 carry += sum / BC_BASE_POW;
1245 sum %= BC_BASE_POW;
1246 }
1247
1248 // Store and set up for next iteration.
1249 ptr_c[i] = (BcDig) sum;
1250 assert(ptr_c[i] < BC_BASE_POW);
1251 sum = carry;
1252 carry = 0;
1253 }
1254
1255 // This should always be true because there should be no carry on the last
1256 // digit; multiplication never goes above the sum of both lengths.
1257 assert(!sum);
1258
1259 c->len = clen;
1260 }
1261
1262 /**
1263 * Does a shifted add or subtract for Karatsuba below. This calls either
1264 * bc_num_addArrays() or bc_num_subArrays().
1265 * @param n An in/out parameter; the first operand and return parameter.
1266 * @param a The second operand.
1267 * @param shift The amount to shift @a n by when adding/subtracting.
1268 * @param op The function to call, either bc_num_addArrays() or
1269 * bc_num_subArrays().
1270 */
1271 static void
bc_num_shiftAddSub(BcNum * restrict n,const BcNum * restrict a,size_t shift,BcNumShiftAddOp op)1272 bc_num_shiftAddSub(BcNum* restrict n, const BcNum* restrict a, size_t shift,
1273 BcNumShiftAddOp op)
1274 {
1275 assert(n->len >= shift + a->len);
1276 assert(!BC_NUM_RDX_VAL(n) && !BC_NUM_RDX_VAL(a));
1277 op(n->num + shift, a->num, a->len);
1278 }
1279
1280 /**
1281 * Implements the Karatsuba algorithm.
1282 */
1283 static void
bc_num_k(const BcNum * a,const BcNum * b,BcNum * restrict c)1284 bc_num_k(const BcNum* a, const BcNum* b, BcNum* restrict c)
1285 {
1286 size_t max, max2, total;
1287 BcNum l1, h1, l2, h2, m2, m1, z0, z1, z2, temp;
1288 BcDig* digs;
1289 BcDig* dig_ptr;
1290 BcNumShiftAddOp op;
1291 bool aone = BC_NUM_ONE(a);
1292 #if BC_ENABLE_LIBRARY
1293 BcVm* vm = bcl_getspecific();
1294 #endif // BC_ENABLE_LIBRARY
1295
1296 assert(BC_NUM_ZERO(c));
1297
1298 if (BC_NUM_ZERO(a) || BC_NUM_ZERO(b)) return;
1299
1300 if (aone || BC_NUM_ONE(b))
1301 {
1302 bc_num_copy(c, aone ? b : a);
1303 if ((aone && BC_NUM_NEG(a)) || BC_NUM_NEG(b)) BC_NUM_NEG_TGL(c);
1304 return;
1305 }
1306
1307 // Shell out to the simple algorithm with certain conditions.
1308 if (a->len < BC_NUM_KARATSUBA_LEN || b->len < BC_NUM_KARATSUBA_LEN)
1309 {
1310 bc_num_m_simp(a, b, c);
1311 return;
1312 }
1313
1314 // We need to calculate the max size of the numbers that can result from the
1315 // operations.
1316 max = BC_MAX(a->len, b->len);
1317 max = BC_MAX(max, BC_NUM_DEF_SIZE);
1318 max2 = (max + 1) / 2;
1319
1320 // Calculate the space needed for all of the temporary allocations. We do
1321 // this to just allocate once.
1322 total = bc_vm_arraySize(BC_NUM_KARATSUBA_ALLOCS, max);
1323
1324 BC_SIG_LOCK;
1325
1326 // Allocate space for all of the temporaries.
1327 digs = dig_ptr = bc_vm_malloc(BC_NUM_SIZE(total));
1328
1329 // Set up the temporaries.
1330 bc_num_setup(&l1, dig_ptr, max);
1331 dig_ptr += max;
1332 bc_num_setup(&h1, dig_ptr, max);
1333 dig_ptr += max;
1334 bc_num_setup(&l2, dig_ptr, max);
1335 dig_ptr += max;
1336 bc_num_setup(&h2, dig_ptr, max);
1337 dig_ptr += max;
1338 bc_num_setup(&m1, dig_ptr, max);
1339 dig_ptr += max;
1340 bc_num_setup(&m2, dig_ptr, max);
1341
1342 // Some temporaries need the ability to grow, so we allocate them
1343 // separately.
1344 max = bc_vm_growSize(max, 1);
1345 bc_num_init(&z0, max);
1346 bc_num_init(&z1, max);
1347 bc_num_init(&z2, max);
1348 max = bc_vm_growSize(max, max) + 1;
1349 bc_num_init(&temp, max);
1350
1351 BC_SETJMP_LOCKED(vm, err);
1352
1353 BC_SIG_UNLOCK;
1354
1355 // First, set up c.
1356 bc_num_expand(c, max);
1357 c->len = max;
1358 // NOLINTNEXTLINE
1359 memset(c->num, 0, BC_NUM_SIZE(c->len));
1360
1361 // Split the parameters.
1362 bc_num_split(a, max2, &l1, &h1);
1363 bc_num_split(b, max2, &l2, &h2);
1364
1365 // Do the subtraction.
1366 bc_num_sub(&h1, &l1, &m1, 0);
1367 bc_num_sub(&l2, &h2, &m2, 0);
1368
1369 // The if statements below are there for efficiency reasons. The best way to
1370 // understand them is to understand the Karatsuba algorithm because now that
1371 // the ollocations and splits are done, the algorithm is pretty
1372 // straightforward.
1373
1374 if (BC_NUM_NONZERO(&h1) && BC_NUM_NONZERO(&h2))
1375 {
1376 assert(BC_NUM_RDX_VALID_NP(h1));
1377 assert(BC_NUM_RDX_VALID_NP(h2));
1378
1379 bc_num_m(&h1, &h2, &z2, 0);
1380 bc_num_clean(&z2);
1381
1382 bc_num_shiftAddSub(c, &z2, max2 * 2, bc_num_addArrays);
1383 bc_num_shiftAddSub(c, &z2, max2, bc_num_addArrays);
1384 }
1385
1386 if (BC_NUM_NONZERO(&l1) && BC_NUM_NONZERO(&l2))
1387 {
1388 assert(BC_NUM_RDX_VALID_NP(l1));
1389 assert(BC_NUM_RDX_VALID_NP(l2));
1390
1391 bc_num_m(&l1, &l2, &z0, 0);
1392 bc_num_clean(&z0);
1393
1394 bc_num_shiftAddSub(c, &z0, max2, bc_num_addArrays);
1395 bc_num_shiftAddSub(c, &z0, 0, bc_num_addArrays);
1396 }
1397
1398 if (BC_NUM_NONZERO(&m1) && BC_NUM_NONZERO(&m2))
1399 {
1400 assert(BC_NUM_RDX_VALID_NP(m1));
1401 assert(BC_NUM_RDX_VALID_NP(m1));
1402
1403 bc_num_m(&m1, &m2, &z1, 0);
1404 bc_num_clean(&z1);
1405
1406 op = (BC_NUM_NEG_NP(m1) != BC_NUM_NEG_NP(m2)) ?
1407 bc_num_subArrays :
1408 bc_num_addArrays;
1409 bc_num_shiftAddSub(c, &z1, max2, op);
1410 }
1411
1412 err:
1413 BC_SIG_MAYLOCK;
1414 free(digs);
1415 bc_num_free(&temp);
1416 bc_num_free(&z2);
1417 bc_num_free(&z1);
1418 bc_num_free(&z0);
1419 BC_LONGJMP_CONT(vm);
1420 }
1421
1422 /**
1423 * Does checks for Karatsuba. It also changes things to ensure that the
1424 * Karatsuba and simple multiplication can treat the numbers as integers. This
1425 * is a BcNumBinOp function.
1426 * @param a The first operand.
1427 * @param b The second operand.
1428 * @param c The return parameter.
1429 * @param scale The current scale.
1430 */
1431 static void
bc_num_m(BcNum * a,BcNum * b,BcNum * restrict c,size_t scale)1432 bc_num_m(BcNum* a, BcNum* b, BcNum* restrict c, size_t scale)
1433 {
1434 BcNum cpa, cpb;
1435 size_t ascale, bscale, ardx, brdx, zero, len, rscale;
1436 // These are meant to quiet warnings on GCC about longjmp() clobbering.
1437 // The problem is real here.
1438 size_t scale1, scale2, realscale;
1439 // These are meant to quiet the GCC longjmp() clobbering, even though it
1440 // does not apply here.
1441 volatile size_t azero;
1442 volatile size_t bzero;
1443 #if BC_ENABLE_LIBRARY
1444 BcVm* vm = bcl_getspecific();
1445 #endif // BC_ENABLE_LIBRARY
1446
1447 assert(BC_NUM_RDX_VALID(a));
1448 assert(BC_NUM_RDX_VALID(b));
1449
1450 bc_num_zero(c);
1451
1452 ascale = a->scale;
1453 bscale = b->scale;
1454
1455 // This sets the final scale according to the bc spec.
1456 scale1 = BC_MAX(scale, ascale);
1457 scale2 = BC_MAX(scale1, bscale);
1458 rscale = ascale + bscale;
1459 realscale = BC_MIN(rscale, scale2);
1460
1461 // If this condition is true, we can use bc_num_mulArray(), which would be
1462 // much faster.
1463 if ((a->len == 1 || b->len == 1) && !a->rdx && !b->rdx)
1464 {
1465 BcNum* operand;
1466 BcBigDig dig;
1467
1468 // Set the correct operands.
1469 if (a->len == 1)
1470 {
1471 dig = (BcBigDig) a->num[0];
1472 operand = b;
1473 }
1474 else
1475 {
1476 dig = (BcBigDig) b->num[0];
1477 operand = a;
1478 }
1479
1480 bc_num_mulArray(operand, dig, c);
1481
1482 // Need to make sure the sign is correct.
1483 if (BC_NUM_NONZERO(c))
1484 {
1485 c->rdx = BC_NUM_NEG_VAL(c, BC_NUM_NEG(a) != BC_NUM_NEG(b));
1486 }
1487
1488 return;
1489 }
1490
1491 assert(BC_NUM_RDX_VALID(a));
1492 assert(BC_NUM_RDX_VALID(b));
1493
1494 BC_SIG_LOCK;
1495
1496 // We need copies because of all of the mutation needed to make Karatsuba
1497 // think the numbers are integers.
1498 bc_num_init(&cpa, a->len + BC_NUM_RDX_VAL(a));
1499 bc_num_init(&cpb, b->len + BC_NUM_RDX_VAL(b));
1500
1501 BC_SETJMP_LOCKED(vm, init_err);
1502
1503 BC_SIG_UNLOCK;
1504
1505 bc_num_copy(&cpa, a);
1506 bc_num_copy(&cpb, b);
1507
1508 assert(BC_NUM_RDX_VALID_NP(cpa));
1509 assert(BC_NUM_RDX_VALID_NP(cpb));
1510
1511 BC_NUM_NEG_CLR_NP(cpa);
1512 BC_NUM_NEG_CLR_NP(cpb);
1513
1514 assert(BC_NUM_RDX_VALID_NP(cpa));
1515 assert(BC_NUM_RDX_VALID_NP(cpb));
1516
1517 // These are what makes them appear like integers.
1518 ardx = BC_NUM_RDX_VAL_NP(cpa) * BC_BASE_DIGS;
1519 bc_num_shiftLeft(&cpa, ardx);
1520
1521 brdx = BC_NUM_RDX_VAL_NP(cpb) * BC_BASE_DIGS;
1522 bc_num_shiftLeft(&cpb, brdx);
1523
1524 // We need to reset the jump here because azero and bzero are used in the
1525 // cleanup, and local variables are not guaranteed to be the same after a
1526 // jump.
1527 BC_SIG_LOCK;
1528
1529 BC_UNSETJMP(vm);
1530
1531 // We want to ignore zero limbs.
1532 azero = bc_num_shiftZero(&cpa);
1533 bzero = bc_num_shiftZero(&cpb);
1534
1535 BC_SETJMP_LOCKED(vm, err);
1536
1537 BC_SIG_UNLOCK;
1538
1539 bc_num_clean(&cpa);
1540 bc_num_clean(&cpb);
1541
1542 bc_num_k(&cpa, &cpb, c);
1543
1544 // The return parameter needs to have its scale set. This is the start. It
1545 // also needs to be shifted by the same amount as a and b have limbs after
1546 // the decimal point.
1547 zero = bc_vm_growSize(azero, bzero);
1548 len = bc_vm_growSize(c->len, zero);
1549
1550 bc_num_expand(c, len);
1551
1552 // Shift c based on the limbs after the decimal point in a and b.
1553 bc_num_shiftLeft(c, (len - c->len) * BC_BASE_DIGS);
1554 bc_num_shiftRight(c, ardx + brdx);
1555
1556 bc_num_retireMul(c, realscale, BC_NUM_NEG(a), BC_NUM_NEG(b));
1557
1558 err:
1559 BC_SIG_MAYLOCK;
1560 bc_num_unshiftZero(&cpb, bzero);
1561 bc_num_unshiftZero(&cpa, azero);
1562 init_err:
1563 BC_SIG_MAYLOCK;
1564 bc_num_free(&cpb);
1565 bc_num_free(&cpa);
1566 BC_LONGJMP_CONT(vm);
1567 }
1568
1569 /**
1570 * Returns true if the BcDig array has non-zero limbs, false otherwise.
1571 * @param a The array to test.
1572 * @param len The length of the array.
1573 * @return True if @a has any non-zero limbs, false otherwise.
1574 */
1575 static bool
bc_num_nonZeroDig(BcDig * restrict a,size_t len)1576 bc_num_nonZeroDig(BcDig* restrict a, size_t len)
1577 {
1578 size_t i;
1579
1580 for (i = len - 1; i < len; --i)
1581 {
1582 if (a[i] != 0) return true;
1583 }
1584
1585 return false;
1586 }
1587
1588 /**
1589 * Compares a BcDig array against a BcNum. This is especially suited for
1590 * division. Returns >0 if @a a is greater than @a b, <0 if it is less, and =0
1591 * if they are equal.
1592 * @param a The array.
1593 * @param b The number.
1594 * @param len The length to assume the arrays are. This is always less than the
1595 * actual length because of how this is implemented.
1596 */
1597 static ssize_t
bc_num_divCmp(const BcDig * a,const BcNum * b,size_t len)1598 bc_num_divCmp(const BcDig* a, const BcNum* b, size_t len)
1599 {
1600 ssize_t cmp;
1601
1602 if (b->len > len && a[len]) cmp = bc_num_compare(a, b->num, len + 1);
1603 else if (b->len <= len)
1604 {
1605 if (a[len]) cmp = 1;
1606 else cmp = bc_num_compare(a, b->num, len);
1607 }
1608 else cmp = -1;
1609
1610 return cmp;
1611 }
1612
1613 /**
1614 * Extends the two operands of a division by BC_BASE_DIGS minus the number of
1615 * digits in the divisor estimate. In other words, it is shifting the numbers in
1616 * order to force the divisor estimate to fill the limb.
1617 * @param a The first operand.
1618 * @param b The second operand.
1619 * @param divisor The divisor estimate.
1620 */
1621 static void
bc_num_divExtend(BcNum * restrict a,BcNum * restrict b,BcBigDig divisor)1622 bc_num_divExtend(BcNum* restrict a, BcNum* restrict b, BcBigDig divisor)
1623 {
1624 size_t pow;
1625
1626 assert(divisor < BC_BASE_POW);
1627
1628 pow = BC_BASE_DIGS - bc_num_log10((size_t) divisor);
1629
1630 bc_num_shiftLeft(a, pow);
1631 bc_num_shiftLeft(b, pow);
1632 }
1633
1634 /**
1635 * Actually does division. This is a rewrite of my original code by Stefan Esser
1636 * from FreeBSD.
1637 * @param a The first operand.
1638 * @param b The second operand.
1639 * @param c The return parameter.
1640 * @param scale The current scale.
1641 */
1642 static void
bc_num_d_long(BcNum * restrict a,BcNum * restrict b,BcNum * restrict c,size_t scale)1643 bc_num_d_long(BcNum* restrict a, BcNum* restrict b, BcNum* restrict c,
1644 size_t scale)
1645 {
1646 BcBigDig divisor;
1647 size_t i, rdx;
1648 // This is volatile and len 2 and reallen exist to quiet the GCC warning
1649 // about clobbering on longjmp(). This one is possible, I think.
1650 volatile size_t len;
1651 size_t len2, reallen;
1652 // This is volatile and realend exists to quiet the GCC warning about
1653 // clobbering on longjmp(). This one is possible, I think.
1654 volatile size_t end;
1655 size_t realend;
1656 BcNum cpb;
1657 // This is volatile and realnonzero exists to quiet the GCC warning about
1658 // clobbering on longjmp(). This one is possible, I think.
1659 volatile bool nonzero;
1660 bool realnonzero;
1661 #if BC_ENABLE_LIBRARY
1662 BcVm* vm = bcl_getspecific();
1663 #endif // BC_ENABLE_LIBRARY
1664
1665 assert(b->len < a->len);
1666
1667 len = b->len;
1668 end = a->len - len;
1669
1670 assert(len >= 1);
1671
1672 // This is a final time to make sure c is big enough and that its array is
1673 // properly zeroed.
1674 bc_num_expand(c, a->len);
1675 // NOLINTNEXTLINE
1676 memset(c->num, 0, c->cap * sizeof(BcDig));
1677
1678 // Setup.
1679 BC_NUM_RDX_SET(c, BC_NUM_RDX_VAL(a));
1680 c->scale = a->scale;
1681 c->len = a->len;
1682
1683 // This is pulling the most significant limb of b in order to establish a
1684 // good "estimate" for the actual divisor.
1685 divisor = (BcBigDig) b->num[len - 1];
1686
1687 // The entire bit of code in this if statement is to tighten the estimate of
1688 // the divisor. The condition asks if b has any other non-zero limbs.
1689 if (len > 1 && bc_num_nonZeroDig(b->num, len - 1))
1690 {
1691 // This takes a little bit of understanding. The "10*BC_BASE_DIGS/6+1"
1692 // results in either 16 for 64-bit 9-digit limbs or 7 for 32-bit 4-digit
1693 // limbs. Then it shifts a 1 by that many, which in both cases, puts the
1694 // result above *half* of the max value a limb can store. Basically,
1695 // this quickly calculates if the divisor is greater than half the max
1696 // of a limb.
1697 nonzero = (divisor > 1 << ((10 * BC_BASE_DIGS) / 6 + 1));
1698
1699 // If the divisor is *not* greater than half the limb...
1700 if (!nonzero)
1701 {
1702 // Extend the parameters by the number of missing digits in the
1703 // divisor.
1704 bc_num_divExtend(a, b, divisor);
1705
1706 // Check bc_num_d(). In there, we grow a again and again. We do it
1707 // again here; we *always* want to be sure it is big enough.
1708 len2 = BC_MAX(a->len, b->len);
1709 bc_num_expand(a, len2 + 1);
1710
1711 // Make a have a zero most significant limb to match the len.
1712 if (len2 + 1 > a->len) a->len = len2 + 1;
1713
1714 // Grab the new divisor estimate, new because the shift has made it
1715 // different.
1716 reallen = b->len;
1717 realend = a->len - reallen;
1718 divisor = (BcBigDig) b->num[reallen - 1];
1719
1720 realnonzero = bc_num_nonZeroDig(b->num, reallen - 1);
1721 }
1722 else
1723 {
1724 realend = end;
1725 realnonzero = nonzero;
1726 }
1727 }
1728 else
1729 {
1730 realend = end;
1731 realnonzero = false;
1732 }
1733
1734 // If b has other nonzero limbs, we want the divisor to be one higher, so
1735 // that it is an upper bound.
1736 divisor += realnonzero;
1737
1738 // Make sure c can fit the new length.
1739 bc_num_expand(c, a->len);
1740 // NOLINTNEXTLINE
1741 memset(c->num, 0, BC_NUM_SIZE(c->cap));
1742
1743 assert(c->scale >= scale);
1744 rdx = BC_NUM_RDX_VAL(c) - BC_NUM_RDX(scale);
1745
1746 BC_SIG_LOCK;
1747
1748 bc_num_init(&cpb, len + 1);
1749
1750 BC_SETJMP_LOCKED(vm, err);
1751
1752 BC_SIG_UNLOCK;
1753
1754 // This is the actual division loop.
1755 for (i = realend - 1; i < realend && i >= rdx && BC_NUM_NONZERO(a); --i)
1756 {
1757 ssize_t cmp;
1758 BcDig* n;
1759 BcBigDig result;
1760
1761 n = a->num + i;
1762 assert(n >= a->num);
1763 result = 0;
1764
1765 cmp = bc_num_divCmp(n, b, len);
1766
1767 // This is true if n is greater than b, which means that division can
1768 // proceed, so this inner loop is the part that implements one instance
1769 // of the division.
1770 while (cmp >= 0)
1771 {
1772 BcBigDig n1, dividend, quotient;
1773
1774 // These should be named obviously enough. Just imagine that it's a
1775 // division of one limb. Because that's what it is.
1776 n1 = (BcBigDig) n[len];
1777 dividend = n1 * BC_BASE_POW + (BcBigDig) n[len - 1];
1778 quotient = (dividend / divisor);
1779
1780 // If this is true, then we can just subtract. Remember: setting
1781 // quotient to 1 is not bad because we already know that n is
1782 // greater than b.
1783 if (quotient <= 1)
1784 {
1785 quotient = 1;
1786 bc_num_subArrays(n, b->num, len);
1787 }
1788 else
1789 {
1790 assert(quotient <= BC_BASE_POW);
1791
1792 // We need to multiply and subtract for a quotient above 1.
1793 bc_num_mulArray(b, (BcBigDig) quotient, &cpb);
1794 bc_num_subArrays(n, cpb.num, cpb.len);
1795 }
1796
1797 // The result is the *real* quotient, by the way, but it might take
1798 // multiple trips around this loop to get it.
1799 result += quotient;
1800 assert(result <= BC_BASE_POW);
1801
1802 // And here's why it might take multiple trips: n might *still* be
1803 // greater than b. So we have to loop again. That's what this is
1804 // setting up for: the condition of the while loop.
1805 if (realnonzero) cmp = bc_num_divCmp(n, b, len);
1806 else cmp = -1;
1807 }
1808
1809 assert(result < BC_BASE_POW);
1810
1811 // Store the actual limb quotient.
1812 c->num[i] = (BcDig) result;
1813 }
1814
1815 err:
1816 BC_SIG_MAYLOCK;
1817 bc_num_free(&cpb);
1818 BC_LONGJMP_CONT(vm);
1819 }
1820
1821 /**
1822 * Implements division. This is a BcNumBinOp function.
1823 * @param a The first operand.
1824 * @param b The second operand.
1825 * @param c The return parameter.
1826 * @param scale The current scale.
1827 */
1828 static void
bc_num_d(BcNum * a,BcNum * b,BcNum * restrict c,size_t scale)1829 bc_num_d(BcNum* a, BcNum* b, BcNum* restrict c, size_t scale)
1830 {
1831 size_t len, cpardx;
1832 BcNum cpa, cpb;
1833 #if BC_ENABLE_LIBRARY
1834 BcVm* vm = bcl_getspecific();
1835 #endif // BC_ENABLE_LIBRARY
1836
1837 if (BC_NUM_ZERO(b)) bc_err(BC_ERR_MATH_DIVIDE_BY_ZERO);
1838
1839 if (BC_NUM_ZERO(a))
1840 {
1841 bc_num_setToZero(c, scale);
1842 return;
1843 }
1844
1845 if (BC_NUM_ONE(b))
1846 {
1847 bc_num_copy(c, a);
1848 bc_num_retireMul(c, scale, BC_NUM_NEG(a), BC_NUM_NEG(b));
1849 return;
1850 }
1851
1852 // If this is true, we can use bc_num_divArray(), which would be faster.
1853 if (!BC_NUM_RDX_VAL(a) && !BC_NUM_RDX_VAL(b) && b->len == 1 && !scale)
1854 {
1855 BcBigDig rem;
1856 bc_num_divArray(a, (BcBigDig) b->num[0], c, &rem);
1857 bc_num_retireMul(c, scale, BC_NUM_NEG(a), BC_NUM_NEG(b));
1858 return;
1859 }
1860
1861 len = bc_num_divReq(a, b, scale);
1862
1863 BC_SIG_LOCK;
1864
1865 // Initialize copies of the parameters. We want the length of the first
1866 // operand copy to be as big as the result because of the way the division
1867 // is implemented.
1868 bc_num_init(&cpa, len);
1869 bc_num_copy(&cpa, a);
1870 bc_num_createCopy(&cpb, b);
1871
1872 BC_SETJMP_LOCKED(vm, err);
1873
1874 BC_SIG_UNLOCK;
1875
1876 len = b->len;
1877
1878 // Like the above comment, we want the copy of the first parameter to be
1879 // larger than the second parameter.
1880 if (len > cpa.len)
1881 {
1882 bc_num_expand(&cpa, bc_vm_growSize(len, 2));
1883 bc_num_extend(&cpa, (len - cpa.len) * BC_BASE_DIGS);
1884 }
1885
1886 cpardx = BC_NUM_RDX_VAL_NP(cpa);
1887 cpa.scale = cpardx * BC_BASE_DIGS;
1888
1889 // This is just setting up the scale in preparation for the division.
1890 bc_num_extend(&cpa, b->scale);
1891 cpardx = BC_NUM_RDX_VAL_NP(cpa) - BC_NUM_RDX(b->scale);
1892 BC_NUM_RDX_SET_NP(cpa, cpardx);
1893 cpa.scale = cpardx * BC_BASE_DIGS;
1894
1895 // Once again, just setting things up, this time to match scale.
1896 if (scale > cpa.scale)
1897 {
1898 bc_num_extend(&cpa, scale);
1899 cpardx = BC_NUM_RDX_VAL_NP(cpa);
1900 cpa.scale = cpardx * BC_BASE_DIGS;
1901 }
1902
1903 // Grow if necessary.
1904 if (cpa.cap == cpa.len) bc_num_expand(&cpa, bc_vm_growSize(cpa.len, 1));
1905
1906 // We want an extra zero in front to make things simpler.
1907 cpa.num[cpa.len++] = 0;
1908
1909 // Still setting things up. Why all of these things are needed is not
1910 // something that can be easily explained, but it has to do with making the
1911 // actual algorithm easier to understand because it can assume a lot of
1912 // things. Thus, you should view all of this setup code as establishing
1913 // assumptions for bc_num_d_long(), where the actual division happens.
1914 if (cpardx == cpa.len) cpa.len = bc_num_nonZeroLen(&cpa);
1915 if (BC_NUM_RDX_VAL_NP(cpb) == cpb.len) cpb.len = bc_num_nonZeroLen(&cpb);
1916 cpb.scale = 0;
1917 BC_NUM_RDX_SET_NP(cpb, 0);
1918
1919 bc_num_d_long(&cpa, &cpb, c, scale);
1920
1921 bc_num_retireMul(c, scale, BC_NUM_NEG(a), BC_NUM_NEG(b));
1922
1923 err:
1924 BC_SIG_MAYLOCK;
1925 bc_num_free(&cpb);
1926 bc_num_free(&cpa);
1927 BC_LONGJMP_CONT(vm);
1928 }
1929
1930 /**
1931 * Implements divmod. This is the actual modulus function; since modulus
1932 * requires a division anyway, this returns the quotient and modulus. Either can
1933 * be thrown out as desired.
1934 * @param a The first operand.
1935 * @param b The second operand.
1936 * @param c The return parameter for the quotient.
1937 * @param d The return parameter for the modulus.
1938 * @param scale The current scale.
1939 * @param ts The scale that the operation should be done to. Yes, it's not
1940 * necessarily the same as scale, per the bc spec.
1941 */
1942 static void
bc_num_r(BcNum * a,BcNum * b,BcNum * restrict c,BcNum * restrict d,size_t scale,size_t ts)1943 bc_num_r(BcNum* a, BcNum* b, BcNum* restrict c, BcNum* restrict d, size_t scale,
1944 size_t ts)
1945 {
1946 BcNum temp;
1947 // realscale is meant to quiet a warning on GCC about longjmp() clobbering.
1948 // This one is real.
1949 size_t realscale;
1950 bool neg;
1951 #if BC_ENABLE_LIBRARY
1952 BcVm* vm = bcl_getspecific();
1953 #endif // BC_ENABLE_LIBRARY
1954
1955 if (BC_NUM_ZERO(b)) bc_err(BC_ERR_MATH_DIVIDE_BY_ZERO);
1956
1957 if (BC_NUM_ZERO(a))
1958 {
1959 bc_num_setToZero(c, ts);
1960 bc_num_setToZero(d, ts);
1961 return;
1962 }
1963
1964 BC_SIG_LOCK;
1965
1966 bc_num_init(&temp, d->cap);
1967
1968 BC_SETJMP_LOCKED(vm, err);
1969
1970 BC_SIG_UNLOCK;
1971
1972 // Division.
1973 bc_num_d(a, b, c, scale);
1974
1975 // We want an extra digit so we can safely truncate.
1976 if (scale) realscale = ts + 1;
1977 else realscale = scale;
1978
1979 assert(BC_NUM_RDX_VALID(c));
1980 assert(BC_NUM_RDX_VALID(b));
1981
1982 // Implement the rest of the (a - (a / b) * b) formula.
1983 bc_num_m(c, b, &temp, realscale);
1984 bc_num_sub(a, &temp, d, realscale);
1985
1986 // Extend if necessary.
1987 if (ts > d->scale && BC_NUM_NONZERO(d)) bc_num_extend(d, ts - d->scale);
1988
1989 neg = BC_NUM_NEG(d);
1990 bc_num_retireMul(d, ts, BC_NUM_NEG(a), BC_NUM_NEG(b));
1991 d->rdx = BC_NUM_NEG_VAL(d, BC_NUM_NONZERO(d) ? neg : false);
1992
1993 err:
1994 BC_SIG_MAYLOCK;
1995 bc_num_free(&temp);
1996 BC_LONGJMP_CONT(vm);
1997 }
1998
1999 /**
2000 * Implements modulus/remainder. (Yes, I know they are different, but not in the
2001 * context of bc.) This is a BcNumBinOp function.
2002 * @param a The first operand.
2003 * @param b The second operand.
2004 * @param c The return parameter.
2005 * @param scale The current scale.
2006 */
2007 static void
bc_num_rem(BcNum * a,BcNum * b,BcNum * restrict c,size_t scale)2008 bc_num_rem(BcNum* a, BcNum* b, BcNum* restrict c, size_t scale)
2009 {
2010 BcNum c1;
2011 size_t ts;
2012 #if BC_ENABLE_LIBRARY
2013 BcVm* vm = bcl_getspecific();
2014 #endif // BC_ENABLE_LIBRARY
2015
2016 ts = bc_vm_growSize(scale, b->scale);
2017 ts = BC_MAX(ts, a->scale);
2018
2019 BC_SIG_LOCK;
2020
2021 // Need a temp for the quotient.
2022 bc_num_init(&c1, bc_num_mulReq(a, b, ts));
2023
2024 BC_SETJMP_LOCKED(vm, err);
2025
2026 BC_SIG_UNLOCK;
2027
2028 bc_num_r(a, b, &c1, c, scale, ts);
2029
2030 err:
2031 BC_SIG_MAYLOCK;
2032 bc_num_free(&c1);
2033 BC_LONGJMP_CONT(vm);
2034 }
2035
2036 /**
2037 * Implements power (exponentiation). This is a BcNumBinOp function.
2038 * @param a The first operand.
2039 * @param b The second operand.
2040 * @param c The return parameter.
2041 * @param scale The current scale.
2042 */
2043 static void
bc_num_p(BcNum * a,BcNum * b,BcNum * restrict c,size_t scale)2044 bc_num_p(BcNum* a, BcNum* b, BcNum* restrict c, size_t scale)
2045 {
2046 BcNum copy, btemp;
2047 BcBigDig exp;
2048 // realscale is meant to quiet a warning on GCC about longjmp() clobbering.
2049 // This one is real.
2050 size_t powrdx, resrdx, realscale;
2051 bool neg;
2052 #if BC_ENABLE_LIBRARY
2053 BcVm* vm = bcl_getspecific();
2054 #endif // BC_ENABLE_LIBRARY
2055
2056 // This is here to silence a warning from GCC.
2057 #if BC_GCC
2058 btemp.len = 0;
2059 btemp.rdx = 0;
2060 btemp.num = NULL;
2061 #endif // BC_GCC
2062
2063 if (BC_ERR(bc_num_nonInt(b, &btemp))) bc_err(BC_ERR_MATH_NON_INTEGER);
2064
2065 assert(btemp.len == 0 || btemp.num != NULL);
2066
2067 if (BC_NUM_ZERO(&btemp))
2068 {
2069 bc_num_one(c);
2070 return;
2071 }
2072
2073 if (BC_NUM_ZERO(a))
2074 {
2075 if (BC_NUM_NEG_NP(btemp)) bc_err(BC_ERR_MATH_DIVIDE_BY_ZERO);
2076 bc_num_setToZero(c, scale);
2077 return;
2078 }
2079
2080 if (BC_NUM_ONE(&btemp))
2081 {
2082 if (!BC_NUM_NEG_NP(btemp)) bc_num_copy(c, a);
2083 else bc_num_inv(a, c, scale);
2084 return;
2085 }
2086
2087 neg = BC_NUM_NEG_NP(btemp);
2088 BC_NUM_NEG_CLR_NP(btemp);
2089
2090 exp = bc_num_bigdig(&btemp);
2091
2092 BC_SIG_LOCK;
2093
2094 bc_num_createCopy(©, a);
2095
2096 BC_SETJMP_LOCKED(vm, err);
2097
2098 BC_SIG_UNLOCK;
2099
2100 // If this is true, then we do not have to do a division, and we need to
2101 // set scale accordingly.
2102 if (!neg)
2103 {
2104 size_t max = BC_MAX(scale, a->scale), scalepow;
2105 scalepow = bc_num_mulOverflow(a->scale, exp);
2106 realscale = BC_MIN(scalepow, max);
2107 }
2108 else realscale = scale;
2109
2110 // This is only implementing the first exponentiation by squaring, until it
2111 // reaches the first time where the square is actually used.
2112 for (powrdx = a->scale; !(exp & 1); exp >>= 1)
2113 {
2114 powrdx <<= 1;
2115 assert(BC_NUM_RDX_VALID_NP(copy));
2116 bc_num_mul(©, ©, ©, powrdx);
2117 }
2118
2119 // Make c a copy of copy for the purpose of saving the squares that should
2120 // be saved.
2121 bc_num_copy(c, ©);
2122 resrdx = powrdx;
2123
2124 // Now finish the exponentiation by squaring, this time saving the squares
2125 // as necessary.
2126 while (exp >>= 1)
2127 {
2128 powrdx <<= 1;
2129 assert(BC_NUM_RDX_VALID_NP(copy));
2130 bc_num_mul(©, ©, ©, powrdx);
2131
2132 // If this is true, we want to save that particular square. This does
2133 // that by multiplying c with copy.
2134 if (exp & 1)
2135 {
2136 resrdx += powrdx;
2137 assert(BC_NUM_RDX_VALID(c));
2138 assert(BC_NUM_RDX_VALID_NP(copy));
2139 bc_num_mul(c, ©, c, resrdx);
2140 }
2141 }
2142
2143 // Invert if necessary.
2144 if (neg) bc_num_inv(c, c, realscale);
2145
2146 // Truncate if necessary.
2147 if (c->scale > realscale) bc_num_truncate(c, c->scale - realscale);
2148
2149 bc_num_clean(c);
2150
2151 err:
2152 BC_SIG_MAYLOCK;
2153 bc_num_free(©);
2154 BC_LONGJMP_CONT(vm);
2155 }
2156
2157 #if BC_ENABLE_EXTRA_MATH
2158 /**
2159 * Implements the places operator. This is a BcNumBinOp function.
2160 * @param a The first operand.
2161 * @param b The second operand.
2162 * @param c The return parameter.
2163 * @param scale The current scale.
2164 */
2165 static void
bc_num_place(BcNum * a,BcNum * b,BcNum * restrict c,size_t scale)2166 bc_num_place(BcNum* a, BcNum* b, BcNum* restrict c, size_t scale)
2167 {
2168 BcBigDig val;
2169
2170 BC_UNUSED(scale);
2171
2172 val = bc_num_intop(a, b, c);
2173
2174 // Just truncate or extend as appropriate.
2175 if (val < c->scale) bc_num_truncate(c, c->scale - val);
2176 else if (val > c->scale) bc_num_extend(c, val - c->scale);
2177 }
2178
2179 /**
2180 * Implements the left shift operator. This is a BcNumBinOp function.
2181 */
2182 static void
bc_num_left(BcNum * a,BcNum * b,BcNum * restrict c,size_t scale)2183 bc_num_left(BcNum* a, BcNum* b, BcNum* restrict c, size_t scale)
2184 {
2185 BcBigDig val;
2186
2187 BC_UNUSED(scale);
2188
2189 val = bc_num_intop(a, b, c);
2190
2191 bc_num_shiftLeft(c, (size_t) val);
2192 }
2193
2194 /**
2195 * Implements the right shift operator. This is a BcNumBinOp function.
2196 */
2197 static void
bc_num_right(BcNum * a,BcNum * b,BcNum * restrict c,size_t scale)2198 bc_num_right(BcNum* a, BcNum* b, BcNum* restrict c, size_t scale)
2199 {
2200 BcBigDig val;
2201
2202 BC_UNUSED(scale);
2203
2204 val = bc_num_intop(a, b, c);
2205
2206 if (BC_NUM_ZERO(c)) return;
2207
2208 bc_num_shiftRight(c, (size_t) val);
2209 }
2210 #endif // BC_ENABLE_EXTRA_MATH
2211
2212 /**
2213 * Prepares for, and calls, a binary operator function. This is probably the
2214 * most important function in the entire file because it establishes assumptions
2215 * that make the rest of the code so easy. Those assumptions include:
2216 *
2217 * - a is not the same pointer as c.
2218 * - b is not the same pointer as c.
2219 * - there is enough room in c for the result.
2220 *
2221 * Without these, this whole function would basically have to be duplicated for
2222 * *all* binary operators.
2223 *
2224 * @param a The first operand.
2225 * @param b The second operand.
2226 * @param c The return parameter.
2227 * @param scale The current scale.
2228 * @param req The number of limbs needed to fit the result.
2229 */
2230 static void
bc_num_binary(BcNum * a,BcNum * b,BcNum * c,size_t scale,BcNumBinOp op,size_t req)2231 bc_num_binary(BcNum* a, BcNum* b, BcNum* c, size_t scale, BcNumBinOp op,
2232 size_t req)
2233 {
2234 BcNum* ptr_a;
2235 BcNum* ptr_b;
2236 BcNum num2;
2237 #if BC_ENABLE_LIBRARY
2238 BcVm* vm = NULL;
2239 #endif // BC_ENABLE_LIBRARY
2240
2241 assert(a != NULL && b != NULL && c != NULL && op != NULL);
2242
2243 assert(BC_NUM_RDX_VALID(a));
2244 assert(BC_NUM_RDX_VALID(b));
2245
2246 BC_SIG_LOCK;
2247
2248 ptr_a = c == a ? &num2 : a;
2249 ptr_b = c == b ? &num2 : b;
2250
2251 // Actually reallocate. If we don't reallocate, we want to expand at the
2252 // very least.
2253 if (c == a || c == b)
2254 {
2255 #if BC_ENABLE_LIBRARY
2256 vm = bcl_getspecific();
2257 #endif // BC_ENABLE_LIBRARY
2258
2259 // NOLINTNEXTLINE
2260 memcpy(&num2, c, sizeof(BcNum));
2261
2262 bc_num_init(c, req);
2263
2264 // Must prepare for cleanup. We want this here so that locals that got
2265 // set stay set since a longjmp() is not guaranteed to preserve locals.
2266 BC_SETJMP_LOCKED(vm, err);
2267 BC_SIG_UNLOCK;
2268 }
2269 else
2270 {
2271 BC_SIG_UNLOCK;
2272 bc_num_expand(c, req);
2273 }
2274
2275 // It is okay for a and b to be the same. If a binary operator function does
2276 // need them to be different, the binary operator function is responsible
2277 // for that.
2278
2279 // Call the actual binary operator function.
2280 op(ptr_a, ptr_b, c, scale);
2281
2282 assert(!BC_NUM_NEG(c) || BC_NUM_NONZERO(c));
2283 assert(BC_NUM_RDX_VAL(c) <= c->len || !c->len);
2284 assert(BC_NUM_RDX_VALID(c));
2285 assert(!c->len || c->num[c->len - 1] || BC_NUM_RDX_VAL(c) == c->len);
2286
2287 err:
2288 // Cleanup only needed if we initialized c to a new number.
2289 if (c == a || c == b)
2290 {
2291 BC_SIG_MAYLOCK;
2292 bc_num_free(&num2);
2293 BC_LONGJMP_CONT(vm);
2294 }
2295 }
2296
2297 /**
2298 * Tests a number string for validity. This function has a history; I originally
2299 * wrote it because I did not trust my parser. Over time, however, I came to
2300 * trust it, so I was able to relegate this function to debug builds only, and I
2301 * used it in assert()'s. But then I created the library, and well, I can't
2302 * trust users, so I reused this for yelling at users.
2303 * @param val The string to check to see if it's a valid number string.
2304 * @return True if the string is a valid number string, false otherwise.
2305 */
2306 bool
bc_num_strValid(const char * restrict val)2307 bc_num_strValid(const char* restrict val)
2308 {
2309 bool radix = false;
2310 size_t i, len = strlen(val);
2311
2312 // Notice that I don't check if there is a negative sign. That is not part
2313 // of a valid number, except in the library. The library-specific code takes
2314 // care of that part.
2315
2316 // Nothing in the string is okay.
2317 if (!len) return true;
2318
2319 // Loop through the characters.
2320 for (i = 0; i < len; ++i)
2321 {
2322 BcDig c = val[i];
2323
2324 // If we have found a radix point...
2325 if (c == '.')
2326 {
2327 // We don't allow two radices.
2328 if (radix) return false;
2329
2330 radix = true;
2331 continue;
2332 }
2333
2334 // We only allow digits and uppercase letters.
2335 if (!(isdigit(c) || isupper(c))) return false;
2336 }
2337
2338 return true;
2339 }
2340
2341 /**
2342 * Parses one character and returns the digit that corresponds to that
2343 * character according to the base.
2344 * @param c The character to parse.
2345 * @param base The base.
2346 * @return The character as a digit.
2347 */
2348 static BcBigDig
bc_num_parseChar(char c,size_t base)2349 bc_num_parseChar(char c, size_t base)
2350 {
2351 assert(isupper(c) || isdigit(c));
2352
2353 // If a letter...
2354 if (isupper(c))
2355 {
2356 #if BC_ENABLE_LIBRARY
2357 BcVm* vm = bcl_getspecific();
2358 #endif // BC_ENABLE_LIBRARY
2359
2360 // This returns the digit that directly corresponds with the letter.
2361 c = BC_NUM_NUM_LETTER(c);
2362
2363 // If the digit is greater than the base, we clamp.
2364 if (BC_DIGIT_CLAMP)
2365 {
2366 c = ((size_t) c) >= base ? (char) base - 1 : c;
2367 }
2368 }
2369 // Straight convert the digit to a number.
2370 else c -= '0';
2371
2372 return (BcBigDig) (uchar) c;
2373 }
2374
2375 /**
2376 * Parses a string as a decimal number. This is separate because it's going to
2377 * be the most used, and it can be heavily optimized for decimal only.
2378 * @param n The number to parse into and return. Must be preallocated.
2379 * @param val The string to parse.
2380 */
2381 static void
bc_num_parseDecimal(BcNum * restrict n,const char * restrict val)2382 bc_num_parseDecimal(BcNum* restrict n, const char* restrict val)
2383 {
2384 size_t len, i, temp, mod;
2385 const char* ptr;
2386 bool zero = true, rdx;
2387 #if BC_ENABLE_LIBRARY
2388 BcVm* vm = bcl_getspecific();
2389 #endif // BC_ENABLE_LIBRARY
2390
2391 // Eat leading zeroes.
2392 for (i = 0; val[i] == '0'; ++i)
2393 {
2394 continue;
2395 }
2396
2397 val += i;
2398 assert(!val[0] || isalnum(val[0]) || val[0] == '.');
2399
2400 // All 0's. We can just return, since this procedure expects a virgin
2401 // (already 0) BcNum.
2402 if (!val[0]) return;
2403
2404 // The length of the string is the length of the number, except it might be
2405 // one bigger because of a decimal point.
2406 len = strlen(val);
2407
2408 // Find the location of the decimal point.
2409 ptr = strchr(val, '.');
2410 rdx = (ptr != NULL);
2411
2412 // We eat leading zeroes again. These leading zeroes are different because
2413 // they will come after the decimal point if they exist, and since that's
2414 // the case, they must be preserved.
2415 for (i = 0; i < len && (zero = (val[i] == '0' || val[i] == '.')); ++i)
2416 {
2417 continue;
2418 }
2419
2420 // Set the scale of the number based on the location of the decimal point.
2421 // The casts to uintptr_t is to ensure that bc does not hit undefined
2422 // behavior when doing math on the values.
2423 n->scale = (size_t) (rdx *
2424 (((uintptr_t) (val + len)) - (((uintptr_t) ptr) + 1)));
2425
2426 // Set rdx.
2427 BC_NUM_RDX_SET(n, BC_NUM_RDX(n->scale));
2428
2429 // Calculate length. First, the length of the integer, then the number of
2430 // digits in the last limb, then the length.
2431 i = len - (ptr == val ? 0 : i) - rdx;
2432 temp = BC_NUM_ROUND_POW(i);
2433 mod = n->scale % BC_BASE_DIGS;
2434 i = mod ? BC_BASE_DIGS - mod : 0;
2435 n->len = ((temp + i) / BC_BASE_DIGS);
2436
2437 // Expand and zero. The plus extra is in case the lack of clamping causes
2438 // the number to overflow the original bounds.
2439 bc_num_expand(n, n->len + !BC_DIGIT_CLAMP);
2440 // NOLINTNEXTLINE
2441 memset(n->num, 0, BC_NUM_SIZE(n->len + !BC_DIGIT_CLAMP));
2442
2443 if (zero)
2444 {
2445 // I think I can set rdx directly to zero here because n should be a
2446 // new number with sign set to false.
2447 n->len = n->rdx = 0;
2448 }
2449 else
2450 {
2451 // There is actually stuff to parse if we make it here. Yay...
2452 BcBigDig exp, pow;
2453
2454 assert(i <= BC_NUM_BIGDIG_MAX);
2455
2456 // The exponent and power.
2457 exp = (BcBigDig) i;
2458 pow = bc_num_pow10[exp];
2459
2460 // Parse loop. We parse backwards because numbers are stored little
2461 // endian.
2462 for (i = len - 1; i < len; --i, ++exp)
2463 {
2464 char c = val[i];
2465
2466 // Skip the decimal point.
2467 if (c == '.') exp -= 1;
2468 else
2469 {
2470 // The index of the limb.
2471 size_t idx = exp / BC_BASE_DIGS;
2472 BcBigDig dig;
2473
2474 if (isupper(c))
2475 {
2476 // Clamp for the base.
2477 if (!BC_DIGIT_CLAMP) c = BC_NUM_NUM_LETTER(c);
2478 else c = 9;
2479 }
2480 else c -= '0';
2481
2482 // Add the digit to the limb. This takes care of overflow from
2483 // lack of clamping.
2484 dig = ((BcBigDig) n->num[idx]) + ((BcBigDig) c) * pow;
2485 if (dig >= BC_BASE_POW)
2486 {
2487 // We cannot go over BC_BASE_POW with clamping.
2488 assert(!BC_DIGIT_CLAMP);
2489
2490 n->num[idx + 1] = (BcDig) (dig / BC_BASE_POW);
2491 n->num[idx] = (BcDig) (dig % BC_BASE_POW);
2492 assert(n->num[idx] >= 0 && n->num[idx] < BC_BASE_POW);
2493 assert(n->num[idx + 1] >= 0 &&
2494 n->num[idx + 1] < BC_BASE_POW);
2495 }
2496 else
2497 {
2498 n->num[idx] = (BcDig) dig;
2499 assert(n->num[idx] >= 0 && n->num[idx] < BC_BASE_POW);
2500 }
2501
2502 // Adjust the power and exponent.
2503 if ((exp + 1) % BC_BASE_DIGS == 0) pow = 1;
2504 else pow *= BC_BASE;
2505 }
2506 }
2507 }
2508
2509 // Make sure to add one to the length if needed from lack of clamping.
2510 n->len += (!BC_DIGIT_CLAMP && n->num[n->len] != 0);
2511 }
2512
2513 /**
2514 * Parse a number in any base (besides decimal).
2515 * @param n The number to parse into and return. Must be preallocated.
2516 * @param val The string to parse.
2517 * @param base The base to parse as.
2518 */
2519 static void
bc_num_parseBase(BcNum * restrict n,const char * restrict val,BcBigDig base)2520 bc_num_parseBase(BcNum* restrict n, const char* restrict val, BcBigDig base)
2521 {
2522 BcNum temp, mult1, mult2, result1, result2;
2523 BcNum* m1;
2524 BcNum* m2;
2525 BcNum* ptr;
2526 char c = 0;
2527 bool zero = true;
2528 BcBigDig v;
2529 size_t digs, len = strlen(val);
2530 // This is volatile to quiet a warning on GCC about longjmp() clobbering.
2531 volatile size_t i;
2532 #if BC_ENABLE_LIBRARY
2533 BcVm* vm = bcl_getspecific();
2534 #endif // BC_ENABLE_LIBRARY
2535
2536 // If zero, just return because the number should be virgin (already 0).
2537 for (i = 0; zero && i < len; ++i)
2538 {
2539 zero = (val[i] == '.' || val[i] == '0');
2540 }
2541 if (zero) return;
2542
2543 BC_SIG_LOCK;
2544
2545 bc_num_init(&temp, BC_NUM_BIGDIG_LOG10);
2546 bc_num_init(&mult1, BC_NUM_BIGDIG_LOG10);
2547
2548 BC_SETJMP_LOCKED(vm, int_err);
2549
2550 BC_SIG_UNLOCK;
2551
2552 // We split parsing into parsing the integer and parsing the fractional
2553 // part.
2554
2555 // Parse the integer part. This is the easy part because we just multiply
2556 // the number by the base, then add the digit.
2557 for (i = 0; i < len && (c = val[i]) && c != '.'; ++i)
2558 {
2559 // Convert the character to a digit.
2560 v = bc_num_parseChar(c, base);
2561
2562 // Multiply the number.
2563 bc_num_mulArray(n, base, &mult1);
2564
2565 // Convert the digit to a number and add.
2566 bc_num_bigdig2num(&temp, v);
2567 bc_num_add(&mult1, &temp, n, 0);
2568 }
2569
2570 // If this condition is true, then we are done. We still need to do cleanup
2571 // though.
2572 if (i == len && !val[i]) goto int_err;
2573
2574 // If we get here, we *must* be at the radix point.
2575 assert(val[i] == '.');
2576
2577 BC_SIG_LOCK;
2578
2579 // Unset the jump to reset in for these new initializations.
2580 BC_UNSETJMP(vm);
2581
2582 bc_num_init(&mult2, BC_NUM_BIGDIG_LOG10);
2583 bc_num_init(&result1, BC_NUM_DEF_SIZE);
2584 bc_num_init(&result2, BC_NUM_DEF_SIZE);
2585 bc_num_one(&mult1);
2586
2587 BC_SETJMP_LOCKED(vm, err);
2588
2589 BC_SIG_UNLOCK;
2590
2591 // Pointers for easy switching.
2592 m1 = &mult1;
2593 m2 = &mult2;
2594
2595 // Parse the fractional part. This is the hard part.
2596 for (i += 1, digs = 0; i < len && (c = val[i]); ++i, ++digs)
2597 {
2598 size_t rdx;
2599
2600 // Convert the character to a digit.
2601 v = bc_num_parseChar(c, base);
2602
2603 // We keep growing result2 according to the base because the more digits
2604 // after the radix, the more significant the digits close to the radix
2605 // should be.
2606 bc_num_mulArray(&result1, base, &result2);
2607
2608 // Convert the digit to a number.
2609 bc_num_bigdig2num(&temp, v);
2610
2611 // Add the digit into the fraction part.
2612 bc_num_add(&result2, &temp, &result1, 0);
2613
2614 // Keep growing m1 and m2 for use after the loop.
2615 bc_num_mulArray(m1, base, m2);
2616
2617 rdx = BC_NUM_RDX_VAL(m2);
2618
2619 if (m2->len < rdx) m2->len = rdx;
2620
2621 // Switch.
2622 ptr = m1;
2623 m1 = m2;
2624 m2 = ptr;
2625 }
2626
2627 // This one cannot be a divide by 0 because mult starts out at 1, then is
2628 // multiplied by base, and base cannot be 0, so mult cannot be 0. And this
2629 // is the reason we keep growing m1 and m2; this division is what converts
2630 // the parsed fractional part from an integer to a fractional part.
2631 bc_num_div(&result1, m1, &result2, digs * 2);
2632
2633 // Pretruncate.
2634 bc_num_truncate(&result2, digs);
2635
2636 // The final add of the integer part to the fractional part.
2637 bc_num_add(n, &result2, n, digs);
2638
2639 // Basic cleanup.
2640 if (BC_NUM_NONZERO(n))
2641 {
2642 if (n->scale < digs) bc_num_extend(n, digs - n->scale);
2643 }
2644 else bc_num_zero(n);
2645
2646 err:
2647 BC_SIG_MAYLOCK;
2648 bc_num_free(&result2);
2649 bc_num_free(&result1);
2650 bc_num_free(&mult2);
2651 int_err:
2652 BC_SIG_MAYLOCK;
2653 bc_num_free(&mult1);
2654 bc_num_free(&temp);
2655 BC_LONGJMP_CONT(vm);
2656 }
2657
2658 /**
2659 * Prints a backslash+newline combo if the number of characters needs it. This
2660 * is really a convenience function.
2661 */
2662 static inline void
bc_num_printNewline(void)2663 bc_num_printNewline(void)
2664 {
2665 #if !BC_ENABLE_LIBRARY
2666 if (vm->nchars >= vm->line_len - 1 && vm->line_len)
2667 {
2668 bc_vm_putchar('\\', bc_flush_none);
2669 bc_vm_putchar('\n', bc_flush_err);
2670 }
2671 #endif // !BC_ENABLE_LIBRARY
2672 }
2673
2674 /**
2675 * Prints a character after a backslash+newline, if needed.
2676 * @param c The character to print.
2677 * @param bslash Whether to print a backslash+newline.
2678 */
2679 static void
bc_num_putchar(int c,bool bslash)2680 bc_num_putchar(int c, bool bslash)
2681 {
2682 if (c != '\n' && bslash) bc_num_printNewline();
2683 bc_vm_putchar(c, bc_flush_save);
2684 }
2685
2686 #if !BC_ENABLE_LIBRARY
2687
2688 /**
2689 * Prints a character for a number's digit. This is for printing for dc's P
2690 * command. This function does not need to worry about radix points. This is a
2691 * BcNumDigitOp.
2692 * @param n The "digit" to print.
2693 * @param len The "length" of the digit, or number of characters that will
2694 * need to be printed for the digit.
2695 * @param rdx True if a decimal (radix) point should be printed.
2696 * @param bslash True if a backslash+newline should be printed if the character
2697 * limit for the line is reached, false otherwise.
2698 */
2699 static void
bc_num_printChar(size_t n,size_t len,bool rdx,bool bslash)2700 bc_num_printChar(size_t n, size_t len, bool rdx, bool bslash)
2701 {
2702 BC_UNUSED(rdx);
2703 BC_UNUSED(len);
2704 BC_UNUSED(bslash);
2705 assert(len == 1);
2706 bc_vm_putchar((uchar) n, bc_flush_save);
2707 }
2708
2709 #endif // !BC_ENABLE_LIBRARY
2710
2711 /**
2712 * Prints a series of characters for large bases. This is for printing in bases
2713 * above hexadecimal. This is a BcNumDigitOp.
2714 * @param n The "digit" to print.
2715 * @param len The "length" of the digit, or number of characters that will
2716 * need to be printed for the digit.
2717 * @param rdx True if a decimal (radix) point should be printed.
2718 * @param bslash True if a backslash+newline should be printed if the character
2719 * limit for the line is reached, false otherwise.
2720 */
2721 static void
bc_num_printDigits(size_t n,size_t len,bool rdx,bool bslash)2722 bc_num_printDigits(size_t n, size_t len, bool rdx, bool bslash)
2723 {
2724 size_t exp, pow;
2725
2726 // If needed, print the radix; otherwise, print a space to separate digits.
2727 bc_num_putchar(rdx ? '.' : ' ', true);
2728
2729 // Calculate the exponent and power.
2730 for (exp = 0, pow = 1; exp < len - 1; ++exp, pow *= BC_BASE)
2731 {
2732 continue;
2733 }
2734
2735 // Print each character individually.
2736 for (exp = 0; exp < len; pow /= BC_BASE, ++exp)
2737 {
2738 // The individual subdigit.
2739 size_t dig = n / pow;
2740
2741 // Take the subdigit away.
2742 n -= dig * pow;
2743
2744 // Print the subdigit.
2745 bc_num_putchar(((uchar) dig) + '0', bslash || exp != len - 1);
2746 }
2747 }
2748
2749 /**
2750 * Prints a character for a number's digit. This is for printing in bases for
2751 * hexadecimal and below because they always print only one character at a time.
2752 * This is a BcNumDigitOp.
2753 * @param n The "digit" to print.
2754 * @param len The "length" of the digit, or number of characters that will
2755 * need to be printed for the digit.
2756 * @param rdx True if a decimal (radix) point should be printed.
2757 * @param bslash True if a backslash+newline should be printed if the character
2758 * limit for the line is reached, false otherwise.
2759 */
2760 static void
bc_num_printHex(size_t n,size_t len,bool rdx,bool bslash)2761 bc_num_printHex(size_t n, size_t len, bool rdx, bool bslash)
2762 {
2763 BC_UNUSED(len);
2764 BC_UNUSED(bslash);
2765
2766 assert(len == 1);
2767
2768 if (rdx) bc_num_putchar('.', true);
2769
2770 bc_num_putchar(bc_num_hex_digits[n], bslash);
2771 }
2772
2773 /**
2774 * Prints a decimal number. This is specially written for optimization since
2775 * this will be used the most and because bc's numbers are already in decimal.
2776 * @param n The number to print.
2777 * @param newline Whether to print backslash+newlines on long enough lines.
2778 */
2779 static void
bc_num_printDecimal(const BcNum * restrict n,bool newline)2780 bc_num_printDecimal(const BcNum* restrict n, bool newline)
2781 {
2782 size_t i, j, rdx = BC_NUM_RDX_VAL(n);
2783 bool zero = true;
2784 size_t buffer[BC_BASE_DIGS];
2785
2786 // Print loop.
2787 for (i = n->len - 1; i < n->len; --i)
2788 {
2789 BcDig n9 = n->num[i];
2790 size_t temp;
2791 bool irdx = (i == rdx - 1);
2792
2793 // Calculate the number of digits in the limb.
2794 zero = (zero & !irdx);
2795 temp = n->scale % BC_BASE_DIGS;
2796 temp = i || !temp ? 0 : BC_BASE_DIGS - temp;
2797
2798 // NOLINTNEXTLINE
2799 memset(buffer, 0, BC_BASE_DIGS * sizeof(size_t));
2800
2801 // Fill the buffer with individual digits.
2802 for (j = 0; n9 && j < BC_BASE_DIGS; ++j)
2803 {
2804 buffer[j] = ((size_t) n9) % BC_BASE;
2805 n9 /= BC_BASE;
2806 }
2807
2808 // Print the digits in the buffer.
2809 for (j = BC_BASE_DIGS - 1; j < BC_BASE_DIGS && j >= temp; --j)
2810 {
2811 // Figure out whether to print the decimal point.
2812 bool print_rdx = (irdx & (j == BC_BASE_DIGS - 1));
2813
2814 // The zero variable helps us skip leading zero digits in the limb.
2815 zero = (zero && buffer[j] == 0);
2816
2817 if (!zero)
2818 {
2819 // While the first three arguments should be self-explanatory,
2820 // the last needs explaining. I don't want to print a newline
2821 // when the last digit to be printed could take the place of the
2822 // backslash rather than being pushed, as a single character, to
2823 // the next line. That's what that last argument does for bc.
2824 bc_num_printHex(buffer[j], 1, print_rdx,
2825 !newline || (j > temp || i != 0));
2826 }
2827 }
2828 }
2829 }
2830
2831 #if BC_ENABLE_EXTRA_MATH
2832
2833 /**
2834 * Prints a number in scientific or engineering format. When doing this, we are
2835 * always printing in decimal.
2836 * @param n The number to print.
2837 * @param eng True if we are in engineering mode.
2838 * @param newline Whether to print backslash+newlines on long enough lines.
2839 */
2840 static void
bc_num_printExponent(const BcNum * restrict n,bool eng,bool newline)2841 bc_num_printExponent(const BcNum* restrict n, bool eng, bool newline)
2842 {
2843 size_t places, mod, nrdx = BC_NUM_RDX_VAL(n);
2844 bool neg = (n->len <= nrdx);
2845 BcNum temp, exp;
2846 BcDig digs[BC_NUM_BIGDIG_LOG10];
2847 #if BC_ENABLE_LIBRARY
2848 BcVm* vm = bcl_getspecific();
2849 #endif // BC_ENABLE_LIBRARY
2850
2851 BC_SIG_LOCK;
2852
2853 bc_num_createCopy(&temp, n);
2854
2855 BC_SETJMP_LOCKED(vm, exit);
2856
2857 BC_SIG_UNLOCK;
2858
2859 // We need to calculate the exponents, and they change based on whether the
2860 // number is all fractional or not, obviously.
2861 if (neg)
2862 {
2863 // Figure out how many limbs after the decimal point is zero.
2864 size_t i, idx = bc_num_nonZeroLen(n) - 1;
2865
2866 places = 1;
2867
2868 // Figure out how much in the last limb is zero.
2869 for (i = BC_BASE_DIGS - 1; i < BC_BASE_DIGS; --i)
2870 {
2871 if (bc_num_pow10[i] > (BcBigDig) n->num[idx]) places += 1;
2872 else break;
2873 }
2874
2875 // Calculate the combination of zero limbs and zero digits in the last
2876 // limb.
2877 places += (nrdx - (idx + 1)) * BC_BASE_DIGS;
2878 mod = places % 3;
2879
2880 // Calculate places if we are in engineering mode.
2881 if (eng && mod != 0) places += 3 - mod;
2882
2883 // Shift the temp to the right place.
2884 bc_num_shiftLeft(&temp, places);
2885 }
2886 else
2887 {
2888 // This is the number of digits that we are supposed to put behind the
2889 // decimal point.
2890 places = bc_num_intDigits(n) - 1;
2891
2892 // Calculate the true number based on whether engineering mode is
2893 // activated.
2894 mod = places % 3;
2895 if (eng && mod != 0) places -= 3 - (3 - mod);
2896
2897 // Shift the temp to the right place.
2898 bc_num_shiftRight(&temp, places);
2899 }
2900
2901 // Print the shifted number.
2902 bc_num_printDecimal(&temp, newline);
2903
2904 // Print the e.
2905 bc_num_putchar('e', !newline);
2906
2907 // Need to explicitly print a zero exponent.
2908 if (!places)
2909 {
2910 bc_num_printHex(0, 1, false, !newline);
2911 goto exit;
2912 }
2913
2914 // Need to print sign for the exponent.
2915 if (neg) bc_num_putchar('-', true);
2916
2917 // Create a temporary for the exponent...
2918 bc_num_setup(&exp, digs, BC_NUM_BIGDIG_LOG10);
2919 bc_num_bigdig2num(&exp, (BcBigDig) places);
2920
2921 /// ..and print it.
2922 bc_num_printDecimal(&exp, newline);
2923
2924 exit:
2925 BC_SIG_MAYLOCK;
2926 bc_num_free(&temp);
2927 BC_LONGJMP_CONT(vm);
2928 }
2929 #endif // BC_ENABLE_EXTRA_MATH
2930
2931 /**
2932 * Converts a number from limbs with base BC_BASE_POW to base @a pow, where
2933 * @a pow is obase^N.
2934 * @param n The number to convert.
2935 * @param rem BC_BASE_POW - @a pow.
2936 * @param pow The power of obase we will convert the number to.
2937 * @param idx The index of the number to start converting at. Doing the
2938 * conversion is O(n^2); we have to sweep through starting at the
2939 * least significant limb
2940 */
2941 static void
bc_num_printFixup(BcNum * restrict n,BcBigDig rem,BcBigDig pow,size_t idx)2942 bc_num_printFixup(BcNum* restrict n, BcBigDig rem, BcBigDig pow, size_t idx)
2943 {
2944 size_t i, len = n->len - idx;
2945 BcBigDig acc;
2946 BcDig* a = n->num + idx;
2947
2948 // Ignore if there's just one limb left. This is the part that requires the
2949 // extra loop after the one calling this function in bc_num_printPrepare().
2950 if (len < 2) return;
2951
2952 // Loop through the remaining limbs and convert. We start at the second limb
2953 // because we pull the value from the previous one as well.
2954 for (i = len - 1; i > 0; --i)
2955 {
2956 // Get the limb and add it to the previous, along with multiplying by
2957 // the remainder because that's the proper overflow. "acc" means
2958 // "accumulator," by the way.
2959 acc = ((BcBigDig) a[i]) * rem + ((BcBigDig) a[i - 1]);
2960
2961 // Store a value in base pow in the previous limb.
2962 a[i - 1] = (BcDig) (acc % pow);
2963
2964 // Divide by the base and accumulate the remaining value in the limb.
2965 acc /= pow;
2966 acc += (BcBigDig) a[i];
2967
2968 // If the accumulator is greater than the base...
2969 if (acc >= BC_BASE_POW)
2970 {
2971 // Do we need to grow?
2972 if (i == len - 1)
2973 {
2974 // Grow.
2975 len = bc_vm_growSize(len, 1);
2976 bc_num_expand(n, bc_vm_growSize(len, idx));
2977
2978 // Update the pointer because it may have moved.
2979 a = n->num + idx;
2980
2981 // Zero out the last limb.
2982 a[len - 1] = 0;
2983 }
2984
2985 // Overflow into the next limb since we are over the base.
2986 a[i + 1] += acc / BC_BASE_POW;
2987 acc %= BC_BASE_POW;
2988 }
2989
2990 assert(acc < BC_BASE_POW);
2991
2992 // Set the limb.
2993 a[i] = (BcDig) acc;
2994 }
2995
2996 // We may have grown the number, so adjust the length.
2997 n->len = len + idx;
2998 }
2999
3000 /**
3001 * Prepares a number for printing in a base that is not a divisor of
3002 * BC_BASE_POW. This basically converts the number from having limbs of base
3003 * BC_BASE_POW to limbs of pow, where pow is obase^N.
3004 * @param n The number to prepare for printing.
3005 * @param rem The remainder of BC_BASE_POW when divided by a power of the base.
3006 * @param pow The power of the base.
3007 */
3008 static void
bc_num_printPrepare(BcNum * restrict n,BcBigDig rem,BcBigDig pow)3009 bc_num_printPrepare(BcNum* restrict n, BcBigDig rem, BcBigDig pow)
3010 {
3011 size_t i;
3012
3013 // Loop from the least significant limb to the most significant limb and
3014 // convert limbs in each pass.
3015 for (i = 0; i < n->len; ++i)
3016 {
3017 bc_num_printFixup(n, rem, pow, i);
3018 }
3019
3020 // bc_num_printFixup() does not do everything it is supposed to, so we do
3021 // the last bit of cleanup here. That cleanup is to ensure that each limb
3022 // is less than pow and to expand the number to fit new limbs as necessary.
3023 for (i = 0; i < n->len; ++i)
3024 {
3025 assert(pow == ((BcBigDig) ((BcDig) pow)));
3026
3027 // If the limb needs fixing...
3028 if (n->num[i] >= (BcDig) pow)
3029 {
3030 // Do we need to grow?
3031 if (i + 1 == n->len)
3032 {
3033 // Grow the number.
3034 n->len = bc_vm_growSize(n->len, 1);
3035 bc_num_expand(n, n->len);
3036
3037 // Without this, we might use uninitialized data.
3038 n->num[i + 1] = 0;
3039 }
3040
3041 assert(pow < BC_BASE_POW);
3042
3043 // Overflow into the next limb.
3044 n->num[i + 1] += n->num[i] / ((BcDig) pow);
3045 n->num[i] %= (BcDig) pow;
3046 }
3047 }
3048 }
3049
3050 static void
bc_num_printNum(BcNum * restrict n,BcBigDig base,size_t len,BcNumDigitOp print,bool newline)3051 bc_num_printNum(BcNum* restrict n, BcBigDig base, size_t len,
3052 BcNumDigitOp print, bool newline)
3053 {
3054 BcVec stack;
3055 BcNum intp, fracp1, fracp2, digit, flen1, flen2;
3056 BcNum* n1;
3057 BcNum* n2;
3058 BcNum* temp;
3059 BcBigDig dig = 0, acc, exp;
3060 BcBigDig* ptr;
3061 size_t i, j, nrdx, idigits;
3062 bool radix;
3063 BcDig digit_digs[BC_NUM_BIGDIG_LOG10 + 1];
3064 #if BC_ENABLE_LIBRARY
3065 BcVm* vm = bcl_getspecific();
3066 #endif // BC_ENABLE_LIBRARY
3067
3068 assert(base > 1);
3069
3070 // Easy case. Even with scale, we just print this.
3071 if (BC_NUM_ZERO(n))
3072 {
3073 print(0, len, false, !newline);
3074 return;
3075 }
3076
3077 // This function uses an algorithm that Stefan Esser <se@freebsd.org> came
3078 // up with to print the integer part of a number. What it does is convert
3079 // intp into a number of the specified base, but it does it directly,
3080 // instead of just doing a series of divisions and printing the remainders
3081 // in reverse order.
3082 //
3083 // Let me explain in a bit more detail:
3084 //
3085 // The algorithm takes the current least significant limb (after intp has
3086 // been converted to an integer) and the next to least significant limb, and
3087 // it converts the least significant limb into one of the specified base,
3088 // putting any overflow into the next to least significant limb. It iterates
3089 // through the whole number, from least significant to most significant,
3090 // doing this conversion. At the end of that iteration, the least
3091 // significant limb is converted, but the others are not, so it iterates
3092 // again, starting at the next to least significant limb. It keeps doing
3093 // that conversion, skipping one more limb than the last time, until all
3094 // limbs have been converted. Then it prints them in reverse order.
3095 //
3096 // That is the gist of the algorithm. It leaves out several things, such as
3097 // the fact that limbs are not always converted into the specified base, but
3098 // into something close, basically a power of the specified base. In
3099 // Stefan's words, "You could consider BcDigs to be of base 10^BC_BASE_DIGS
3100 // in the normal case and obase^N for the largest value of N that satisfies
3101 // obase^N <= 10^BC_BASE_DIGS. [This means that] the result is not in base
3102 // "obase", but in base "obase^N", which happens to be printable as a number
3103 // of base "obase" without consideration for neighbouring BcDigs." This fact
3104 // is what necessitates the existence of the loop later in this function.
3105 //
3106 // The conversion happens in bc_num_printPrepare() where the outer loop
3107 // happens and bc_num_printFixup() where the inner loop, or actual
3108 // conversion, happens. In other words, bc_num_printPrepare() is where the
3109 // loop that starts at the least significant limb and goes to the most
3110 // significant limb. Then, on every iteration of its loop, it calls
3111 // bc_num_printFixup(), which has the inner loop of actually converting
3112 // the limbs it passes into limbs of base obase^N rather than base
3113 // BC_BASE_POW.
3114
3115 nrdx = BC_NUM_RDX_VAL(n);
3116
3117 BC_SIG_LOCK;
3118
3119 // The stack is what allows us to reverse the digits for printing.
3120 bc_vec_init(&stack, sizeof(BcBigDig), BC_DTOR_NONE);
3121 bc_num_init(&fracp1, nrdx);
3122
3123 // intp will be the "integer part" of the number, so copy it.
3124 bc_num_createCopy(&intp, n);
3125
3126 BC_SETJMP_LOCKED(vm, err);
3127
3128 BC_SIG_UNLOCK;
3129
3130 // Make intp an integer.
3131 bc_num_truncate(&intp, intp.scale);
3132
3133 // Get the fractional part out.
3134 bc_num_sub(n, &intp, &fracp1, 0);
3135
3136 // If the base is not the same as the last base used for printing, we need
3137 // to update the cached exponent and power. Yes, we cache the values of the
3138 // exponent and power. That is to prevent us from calculating them every
3139 // time because printing will probably happen multiple times on the same
3140 // base.
3141 if (base != vm->last_base)
3142 {
3143 vm->last_pow = 1;
3144 vm->last_exp = 0;
3145
3146 // Calculate the exponent and power.
3147 while (vm->last_pow * base <= BC_BASE_POW)
3148 {
3149 vm->last_pow *= base;
3150 vm->last_exp += 1;
3151 }
3152
3153 // Also, the remainder and base itself.
3154 vm->last_rem = BC_BASE_POW - vm->last_pow;
3155 vm->last_base = base;
3156 }
3157
3158 exp = vm->last_exp;
3159
3160 // If vm->last_rem is 0, then the base we are printing in is a divisor of
3161 // BC_BASE_POW, which is the easy case because it means that BC_BASE_POW is
3162 // a power of obase, and no conversion is needed. If it *is* 0, then we have
3163 // the hard case, and we have to prepare the number for the base.
3164 if (vm->last_rem != 0)
3165 {
3166 bc_num_printPrepare(&intp, vm->last_rem, vm->last_pow);
3167 }
3168
3169 // After the conversion comes the surprisingly easy part. From here on out,
3170 // this is basically naive code that I wrote, adjusted for the larger bases.
3171
3172 // Fill the stack of digits for the integer part.
3173 for (i = 0; i < intp.len; ++i)
3174 {
3175 // Get the limb.
3176 acc = (BcBigDig) intp.num[i];
3177
3178 // Turn the limb into digits of base obase.
3179 for (j = 0; j < exp && (i < intp.len - 1 || acc != 0); ++j)
3180 {
3181 // This condition is true if we are not at the last digit.
3182 if (j != exp - 1)
3183 {
3184 dig = acc % base;
3185 acc /= base;
3186 }
3187 else
3188 {
3189 dig = acc;
3190 acc = 0;
3191 }
3192
3193 assert(dig < base);
3194
3195 // Push the digit onto the stack.
3196 bc_vec_push(&stack, &dig);
3197 }
3198
3199 assert(acc == 0);
3200 }
3201
3202 // Go through the stack backwards and print each digit.
3203 for (i = 0; i < stack.len; ++i)
3204 {
3205 ptr = bc_vec_item_rev(&stack, i);
3206
3207 assert(ptr != NULL);
3208
3209 // While the first three arguments should be self-explanatory, the last
3210 // needs explaining. I don't want to print a newline when the last digit
3211 // to be printed could take the place of the backslash rather than being
3212 // pushed, as a single character, to the next line. That's what that
3213 // last argument does for bc.
3214 print(*ptr, len, false,
3215 !newline || (n->scale != 0 || i == stack.len - 1));
3216 }
3217
3218 // We are done if there is no fractional part.
3219 if (!n->scale) goto err;
3220
3221 BC_SIG_LOCK;
3222
3223 // Reset the jump because some locals are changing.
3224 BC_UNSETJMP(vm);
3225
3226 bc_num_init(&fracp2, nrdx);
3227 bc_num_setup(&digit, digit_digs, sizeof(digit_digs) / sizeof(BcDig));
3228 bc_num_init(&flen1, BC_NUM_BIGDIG_LOG10);
3229 bc_num_init(&flen2, BC_NUM_BIGDIG_LOG10);
3230
3231 BC_SETJMP_LOCKED(vm, frac_err);
3232
3233 BC_SIG_UNLOCK;
3234
3235 bc_num_one(&flen1);
3236
3237 radix = true;
3238
3239 // Pointers for easy switching.
3240 n1 = &flen1;
3241 n2 = &flen2;
3242
3243 fracp2.scale = n->scale;
3244 BC_NUM_RDX_SET_NP(fracp2, BC_NUM_RDX(fracp2.scale));
3245
3246 // As long as we have not reached the scale of the number, keep printing.
3247 while ((idigits = bc_num_intDigits(n1)) <= n->scale)
3248 {
3249 // These numbers will keep growing.
3250 bc_num_expand(&fracp2, fracp1.len + 1);
3251 bc_num_mulArray(&fracp1, base, &fracp2);
3252
3253 nrdx = BC_NUM_RDX_VAL_NP(fracp2);
3254
3255 // Ensure an invariant.
3256 if (fracp2.len < nrdx) fracp2.len = nrdx;
3257
3258 // fracp is guaranteed to be non-negative and small enough.
3259 dig = bc_num_bigdig2(&fracp2);
3260
3261 // Convert the digit to a number and subtract it from the number.
3262 bc_num_bigdig2num(&digit, dig);
3263 bc_num_sub(&fracp2, &digit, &fracp1, 0);
3264
3265 // While the first three arguments should be self-explanatory, the last
3266 // needs explaining. I don't want to print a newline when the last digit
3267 // to be printed could take the place of the backslash rather than being
3268 // pushed, as a single character, to the next line. That's what that
3269 // last argument does for bc.
3270 print(dig, len, radix, !newline || idigits != n->scale);
3271
3272 // Update the multipliers.
3273 bc_num_mulArray(n1, base, n2);
3274
3275 radix = false;
3276
3277 // Switch.
3278 temp = n1;
3279 n1 = n2;
3280 n2 = temp;
3281 }
3282
3283 frac_err:
3284 BC_SIG_MAYLOCK;
3285 bc_num_free(&flen2);
3286 bc_num_free(&flen1);
3287 bc_num_free(&fracp2);
3288 err:
3289 BC_SIG_MAYLOCK;
3290 bc_num_free(&fracp1);
3291 bc_num_free(&intp);
3292 bc_vec_free(&stack);
3293 BC_LONGJMP_CONT(vm);
3294 }
3295
3296 /**
3297 * Prints a number in the specified base, or rather, figures out which function
3298 * to call to print the number in the specified base and calls it.
3299 * @param n The number to print.
3300 * @param base The base to print in.
3301 * @param newline Whether to print backslash+newlines on long enough lines.
3302 */
3303 static void
bc_num_printBase(BcNum * restrict n,BcBigDig base,bool newline)3304 bc_num_printBase(BcNum* restrict n, BcBigDig base, bool newline)
3305 {
3306 size_t width;
3307 BcNumDigitOp print;
3308 bool neg = BC_NUM_NEG(n);
3309
3310 // Clear the sign because it makes the actual printing easier when we have
3311 // to do math.
3312 BC_NUM_NEG_CLR(n);
3313
3314 // Bases at hexadecimal and below are printed as one character, larger bases
3315 // are printed as a series of digits separated by spaces.
3316 if (base <= BC_NUM_MAX_POSIX_IBASE)
3317 {
3318 width = 1;
3319 print = bc_num_printHex;
3320 }
3321 else
3322 {
3323 assert(base <= BC_BASE_POW);
3324 width = bc_num_log10(base - 1);
3325 print = bc_num_printDigits;
3326 }
3327
3328 // Print.
3329 bc_num_printNum(n, base, width, print, newline);
3330
3331 // Reset the sign.
3332 n->rdx = BC_NUM_NEG_VAL(n, neg);
3333 }
3334
3335 #if !BC_ENABLE_LIBRARY
3336
3337 void
bc_num_stream(BcNum * restrict n)3338 bc_num_stream(BcNum* restrict n)
3339 {
3340 bc_num_printNum(n, BC_NUM_STREAM_BASE, 1, bc_num_printChar, false);
3341 }
3342
3343 #endif // !BC_ENABLE_LIBRARY
3344
3345 void
bc_num_setup(BcNum * restrict n,BcDig * restrict num,size_t cap)3346 bc_num_setup(BcNum* restrict n, BcDig* restrict num, size_t cap)
3347 {
3348 assert(n != NULL);
3349 n->num = num;
3350 n->cap = cap;
3351 bc_num_zero(n);
3352 }
3353
3354 void
bc_num_init(BcNum * restrict n,size_t req)3355 bc_num_init(BcNum* restrict n, size_t req)
3356 {
3357 BcDig* num;
3358
3359 BC_SIG_ASSERT_LOCKED;
3360
3361 assert(n != NULL);
3362
3363 // BC_NUM_DEF_SIZE is set to be about the smallest allocation size that
3364 // malloc() returns in practice, so just use it.
3365 req = req >= BC_NUM_DEF_SIZE ? req : BC_NUM_DEF_SIZE;
3366
3367 // If we can't use a temp, allocate.
3368 if (req != BC_NUM_DEF_SIZE) num = bc_vm_malloc(BC_NUM_SIZE(req));
3369 else
3370 {
3371 num = bc_vm_getTemp() == NULL ? bc_vm_malloc(BC_NUM_SIZE(req)) :
3372 bc_vm_takeTemp();
3373 }
3374
3375 bc_num_setup(n, num, req);
3376 }
3377
3378 void
bc_num_clear(BcNum * restrict n)3379 bc_num_clear(BcNum* restrict n)
3380 {
3381 n->num = NULL;
3382 n->cap = 0;
3383 }
3384
3385 void
bc_num_free(void * num)3386 bc_num_free(void* num)
3387 {
3388 BcNum* n = (BcNum*) num;
3389
3390 BC_SIG_ASSERT_LOCKED;
3391
3392 assert(n != NULL);
3393
3394 if (n->cap == BC_NUM_DEF_SIZE) bc_vm_addTemp(n->num);
3395 else free(n->num);
3396 }
3397
3398 void
bc_num_copy(BcNum * d,const BcNum * s)3399 bc_num_copy(BcNum* d, const BcNum* s)
3400 {
3401 assert(d != NULL && s != NULL);
3402
3403 if (d == s) return;
3404
3405 bc_num_expand(d, s->len);
3406 d->len = s->len;
3407
3408 // I can just copy directly here because the sign *and* rdx will be
3409 // properly preserved.
3410 d->rdx = s->rdx;
3411 d->scale = s->scale;
3412 // NOLINTNEXTLINE
3413 memcpy(d->num, s->num, BC_NUM_SIZE(d->len));
3414 }
3415
3416 void
bc_num_createCopy(BcNum * d,const BcNum * s)3417 bc_num_createCopy(BcNum* d, const BcNum* s)
3418 {
3419 BC_SIG_ASSERT_LOCKED;
3420 bc_num_init(d, s->len);
3421 bc_num_copy(d, s);
3422 }
3423
3424 void
bc_num_createFromBigdig(BcNum * restrict n,BcBigDig val)3425 bc_num_createFromBigdig(BcNum* restrict n, BcBigDig val)
3426 {
3427 BC_SIG_ASSERT_LOCKED;
3428 bc_num_init(n, BC_NUM_BIGDIG_LOG10);
3429 bc_num_bigdig2num(n, val);
3430 }
3431
3432 size_t
bc_num_scale(const BcNum * restrict n)3433 bc_num_scale(const BcNum* restrict n)
3434 {
3435 return n->scale;
3436 }
3437
3438 size_t
bc_num_len(const BcNum * restrict n)3439 bc_num_len(const BcNum* restrict n)
3440 {
3441 size_t len = n->len;
3442
3443 // Always return at least 1.
3444 if (BC_NUM_ZERO(n)) return n->scale ? n->scale : 1;
3445
3446 // If this is true, there is no integer portion of the number.
3447 if (BC_NUM_RDX_VAL(n) == len)
3448 {
3449 // We have to take into account the fact that some of the digits right
3450 // after the decimal could be zero. If that is the case, we need to
3451 // ignore them until we hit the first non-zero digit.
3452
3453 size_t zero, scale;
3454
3455 // The number of limbs with non-zero digits.
3456 len = bc_num_nonZeroLen(n);
3457
3458 // Get the number of digits in the last limb.
3459 scale = n->scale % BC_BASE_DIGS;
3460 scale = scale ? scale : BC_BASE_DIGS;
3461
3462 // Get the number of zero digits.
3463 zero = bc_num_zeroDigits(n->num + len - 1);
3464
3465 // Calculate the true length.
3466 len = len * BC_BASE_DIGS - zero - (BC_BASE_DIGS - scale);
3467 }
3468 // Otherwise, count the number of int digits and return that plus the scale.
3469 else len = bc_num_intDigits(n) + n->scale;
3470
3471 return len;
3472 }
3473
3474 void
bc_num_parse(BcNum * restrict n,const char * restrict val,BcBigDig base)3475 bc_num_parse(BcNum* restrict n, const char* restrict val, BcBigDig base)
3476 {
3477 #if BC_DEBUG
3478 #if BC_ENABLE_LIBRARY
3479 BcVm* vm = bcl_getspecific();
3480 #endif // BC_ENABLE_LIBRARY
3481 #endif // BC_DEBUG
3482
3483 assert(n != NULL && val != NULL && base);
3484 assert(base >= BC_NUM_MIN_BASE && base <= vm->maxes[BC_PROG_GLOBALS_IBASE]);
3485 assert(bc_num_strValid(val));
3486
3487 // A one character number is *always* parsed as though the base was the
3488 // maximum allowed ibase, per the bc spec.
3489 if (!val[1])
3490 {
3491 BcBigDig dig = bc_num_parseChar(val[0], BC_NUM_MAX_LBASE);
3492 bc_num_bigdig2num(n, dig);
3493 }
3494 else if (base == BC_BASE) bc_num_parseDecimal(n, val);
3495 else bc_num_parseBase(n, val, base);
3496
3497 assert(BC_NUM_RDX_VALID(n));
3498 }
3499
3500 void
bc_num_print(BcNum * restrict n,BcBigDig base,bool newline)3501 bc_num_print(BcNum* restrict n, BcBigDig base, bool newline)
3502 {
3503 assert(n != NULL);
3504 assert(BC_ENABLE_EXTRA_MATH || base >= BC_NUM_MIN_BASE);
3505
3506 // We may need a newline, just to start.
3507 bc_num_printNewline();
3508
3509 if (BC_NUM_NONZERO(n))
3510 {
3511 #if BC_ENABLE_LIBRARY
3512 BcVm* vm = bcl_getspecific();
3513 #endif // BC_ENABLE_LIBRARY
3514
3515 // Print the sign.
3516 if (BC_NUM_NEG(n)) bc_num_putchar('-', true);
3517
3518 // Print the leading zero if necessary.
3519 if (BC_Z && BC_NUM_RDX_VAL(n) == n->len)
3520 {
3521 bc_num_printHex(0, 1, false, !newline);
3522 }
3523 }
3524
3525 // Short-circuit 0.
3526 if (BC_NUM_ZERO(n)) bc_num_printHex(0, 1, false, !newline);
3527 else if (base == BC_BASE) bc_num_printDecimal(n, newline);
3528 #if BC_ENABLE_EXTRA_MATH
3529 else if (base == 0 || base == 1)
3530 {
3531 bc_num_printExponent(n, base != 0, newline);
3532 }
3533 #endif // BC_ENABLE_EXTRA_MATH
3534 else bc_num_printBase(n, base, newline);
3535
3536 if (newline) bc_num_putchar('\n', false);
3537 }
3538
3539 BcBigDig
bc_num_bigdig2(const BcNum * restrict n)3540 bc_num_bigdig2(const BcNum* restrict n)
3541 {
3542 #if BC_DEBUG
3543 #if BC_ENABLE_LIBRARY
3544 BcVm* vm = bcl_getspecific();
3545 #endif // BC_ENABLE_LIBRARY
3546 #endif // BC_DEBUG
3547
3548 // This function returns no errors because it's guaranteed to succeed if
3549 // its preconditions are met. Those preconditions include both n needs to
3550 // be non-NULL, n being non-negative, and n being less than vm->max. If all
3551 // of that is true, then we can just convert without worrying about negative
3552 // errors or overflow.
3553
3554 BcBigDig r = 0;
3555 size_t nrdx = BC_NUM_RDX_VAL(n);
3556
3557 assert(n != NULL);
3558 assert(!BC_NUM_NEG(n));
3559 assert(bc_num_cmp(n, &vm->max) < 0);
3560 assert(n->len - nrdx <= 3);
3561
3562 // There is a small speed win from unrolling the loop here, and since it
3563 // only adds 53 bytes, I decided that it was worth it.
3564 switch (n->len - nrdx)
3565 {
3566 case 3:
3567 {
3568 r = (BcBigDig) n->num[nrdx + 2];
3569
3570 // Fallthrough.
3571 BC_FALLTHROUGH
3572 }
3573
3574 case 2:
3575 {
3576 r = r * BC_BASE_POW + (BcBigDig) n->num[nrdx + 1];
3577
3578 // Fallthrough.
3579 BC_FALLTHROUGH
3580 }
3581
3582 case 1:
3583 {
3584 r = r * BC_BASE_POW + (BcBigDig) n->num[nrdx];
3585 }
3586 }
3587
3588 return r;
3589 }
3590
3591 BcBigDig
bc_num_bigdig(const BcNum * restrict n)3592 bc_num_bigdig(const BcNum* restrict n)
3593 {
3594 #if BC_ENABLE_LIBRARY
3595 BcVm* vm = bcl_getspecific();
3596 #endif // BC_ENABLE_LIBRARY
3597
3598 assert(n != NULL);
3599
3600 // This error checking is extremely important, and if you do not have a
3601 // guarantee that converting a number will always succeed in a particular
3602 // case, you *must* call this function to get these error checks. This
3603 // includes all instances of numbers inputted by the user or calculated by
3604 // the user. Otherwise, you can call the faster bc_num_bigdig2().
3605 if (BC_ERR(BC_NUM_NEG(n))) bc_err(BC_ERR_MATH_NEGATIVE);
3606 if (BC_ERR(bc_num_cmp(n, &vm->max) >= 0)) bc_err(BC_ERR_MATH_OVERFLOW);
3607
3608 return bc_num_bigdig2(n);
3609 }
3610
3611 void
bc_num_bigdig2num(BcNum * restrict n,BcBigDig val)3612 bc_num_bigdig2num(BcNum* restrict n, BcBigDig val)
3613 {
3614 BcDig* ptr;
3615 size_t i;
3616
3617 assert(n != NULL);
3618
3619 bc_num_zero(n);
3620
3621 // Already 0.
3622 if (!val) return;
3623
3624 // Expand first. This is the only way this function can fail, and it's a
3625 // fatal error.
3626 bc_num_expand(n, BC_NUM_BIGDIG_LOG10);
3627
3628 // The conversion is easy because numbers are laid out in little-endian
3629 // order.
3630 for (ptr = n->num, i = 0; val; ++i, val /= BC_BASE_POW)
3631 {
3632 ptr[i] = val % BC_BASE_POW;
3633 }
3634
3635 n->len = i;
3636 }
3637
3638 #if BC_ENABLE_EXTRA_MATH
3639
3640 void
bc_num_rng(const BcNum * restrict n,BcRNG * rng)3641 bc_num_rng(const BcNum* restrict n, BcRNG* rng)
3642 {
3643 BcNum temp, temp2, intn, frac;
3644 BcRand state1, state2, inc1, inc2;
3645 size_t nrdx = BC_NUM_RDX_VAL(n);
3646 #if BC_ENABLE_LIBRARY
3647 BcVm* vm = bcl_getspecific();
3648 #endif // BC_ENABLE_LIBRARY
3649
3650 // This function holds the secret of how I interpret a seed number for the
3651 // PRNG. Well, it's actually in the development manual
3652 // (manuals/development.md#pseudo-random-number-generator), so look there
3653 // before you try to understand this.
3654
3655 BC_SIG_LOCK;
3656
3657 bc_num_init(&temp, n->len);
3658 bc_num_init(&temp2, n->len);
3659 bc_num_init(&frac, nrdx);
3660 bc_num_init(&intn, bc_num_int(n));
3661
3662 BC_SETJMP_LOCKED(vm, err);
3663
3664 BC_SIG_UNLOCK;
3665
3666 assert(BC_NUM_RDX_VALID_NP(vm->max));
3667
3668 // NOLINTNEXTLINE
3669 memcpy(frac.num, n->num, BC_NUM_SIZE(nrdx));
3670 frac.len = nrdx;
3671 BC_NUM_RDX_SET_NP(frac, nrdx);
3672 frac.scale = n->scale;
3673
3674 assert(BC_NUM_RDX_VALID_NP(frac));
3675 assert(BC_NUM_RDX_VALID_NP(vm->max2));
3676
3677 // Multiply the fraction and truncate so that it's an integer. The
3678 // truncation is what clamps it, by the way.
3679 bc_num_mul(&frac, &vm->max2, &temp, 0);
3680 bc_num_truncate(&temp, temp.scale);
3681 bc_num_copy(&frac, &temp);
3682
3683 // Get the integer.
3684 // NOLINTNEXTLINE
3685 memcpy(intn.num, n->num + nrdx, BC_NUM_SIZE(bc_num_int(n)));
3686 intn.len = bc_num_int(n);
3687
3688 // This assert is here because it has to be true. It is also here to justify
3689 // some optimizations.
3690 assert(BC_NUM_NONZERO(&vm->max));
3691
3692 // If there *was* a fractional part...
3693 if (BC_NUM_NONZERO(&frac))
3694 {
3695 // This divmod splits frac into the two state parts.
3696 bc_num_divmod(&frac, &vm->max, &temp, &temp2, 0);
3697
3698 // frac is guaranteed to be smaller than vm->max * vm->max (pow).
3699 // This means that when dividing frac by vm->max, as above, the
3700 // quotient and remainder are both guaranteed to be less than vm->max,
3701 // which means we can use bc_num_bigdig2() here and not worry about
3702 // overflow.
3703 state1 = (BcRand) bc_num_bigdig2(&temp2);
3704 state2 = (BcRand) bc_num_bigdig2(&temp);
3705 }
3706 else state1 = state2 = 0;
3707
3708 // If there *was* an integer part...
3709 if (BC_NUM_NONZERO(&intn))
3710 {
3711 // This divmod splits intn into the two inc parts.
3712 bc_num_divmod(&intn, &vm->max, &temp, &temp2, 0);
3713
3714 // Because temp2 is the mod of vm->max, from above, it is guaranteed
3715 // to be small enough to use bc_num_bigdig2().
3716 inc1 = (BcRand) bc_num_bigdig2(&temp2);
3717
3718 // Clamp the second inc part.
3719 if (bc_num_cmp(&temp, &vm->max) >= 0)
3720 {
3721 bc_num_copy(&temp2, &temp);
3722 bc_num_mod(&temp2, &vm->max, &temp, 0);
3723 }
3724
3725 // The if statement above ensures that temp is less than vm->max, which
3726 // means that we can use bc_num_bigdig2() here.
3727 inc2 = (BcRand) bc_num_bigdig2(&temp);
3728 }
3729 else inc1 = inc2 = 0;
3730
3731 bc_rand_seed(rng, state1, state2, inc1, inc2);
3732
3733 err:
3734 BC_SIG_MAYLOCK;
3735 bc_num_free(&intn);
3736 bc_num_free(&frac);
3737 bc_num_free(&temp2);
3738 bc_num_free(&temp);
3739 BC_LONGJMP_CONT(vm);
3740 }
3741
3742 void
bc_num_createFromRNG(BcNum * restrict n,BcRNG * rng)3743 bc_num_createFromRNG(BcNum* restrict n, BcRNG* rng)
3744 {
3745 BcRand s1, s2, i1, i2;
3746 BcNum conv, temp1, temp2, temp3;
3747 BcDig temp1_num[BC_RAND_NUM_SIZE], temp2_num[BC_RAND_NUM_SIZE];
3748 BcDig conv_num[BC_NUM_BIGDIG_LOG10];
3749 #if BC_ENABLE_LIBRARY
3750 BcVm* vm = bcl_getspecific();
3751 #endif // BC_ENABLE_LIBRARY
3752
3753 BC_SIG_LOCK;
3754
3755 bc_num_init(&temp3, 2 * BC_RAND_NUM_SIZE);
3756
3757 BC_SETJMP_LOCKED(vm, err);
3758
3759 BC_SIG_UNLOCK;
3760
3761 bc_num_setup(&temp1, temp1_num, sizeof(temp1_num) / sizeof(BcDig));
3762 bc_num_setup(&temp2, temp2_num, sizeof(temp2_num) / sizeof(BcDig));
3763 bc_num_setup(&conv, conv_num, sizeof(conv_num) / sizeof(BcDig));
3764
3765 // This assert is here because it has to be true. It is also here to justify
3766 // the assumption that vm->max is not zero.
3767 assert(BC_NUM_NONZERO(&vm->max));
3768
3769 // Because this is true, we can just ignore math errors that would happen
3770 // otherwise.
3771 assert(BC_NUM_NONZERO(&vm->max2));
3772
3773 bc_rand_getRands(rng, &s1, &s2, &i1, &i2);
3774
3775 // Put the second piece of state into a number.
3776 bc_num_bigdig2num(&conv, (BcBigDig) s2);
3777
3778 assert(BC_NUM_RDX_VALID_NP(conv));
3779
3780 // Multiply by max to make room for the first piece of state.
3781 bc_num_mul(&conv, &vm->max, &temp1, 0);
3782
3783 // Add in the first piece of state.
3784 bc_num_bigdig2num(&conv, (BcBigDig) s1);
3785 bc_num_add(&conv, &temp1, &temp2, 0);
3786
3787 // Divide to make it an entirely fractional part.
3788 bc_num_div(&temp2, &vm->max2, &temp3, BC_RAND_STATE_BITS);
3789
3790 // Now start on the increment parts. It's the same process without the
3791 // divide, so put the second piece of increment into a number.
3792 bc_num_bigdig2num(&conv, (BcBigDig) i2);
3793
3794 assert(BC_NUM_RDX_VALID_NP(conv));
3795
3796 // Multiply by max to make room for the first piece of increment.
3797 bc_num_mul(&conv, &vm->max, &temp1, 0);
3798
3799 // Add in the first piece of increment.
3800 bc_num_bigdig2num(&conv, (BcBigDig) i1);
3801 bc_num_add(&conv, &temp1, &temp2, 0);
3802
3803 // Now add the two together.
3804 bc_num_add(&temp2, &temp3, n, 0);
3805
3806 assert(BC_NUM_RDX_VALID(n));
3807
3808 err:
3809 BC_SIG_MAYLOCK;
3810 bc_num_free(&temp3);
3811 BC_LONGJMP_CONT(vm);
3812 }
3813
3814 void
bc_num_irand(BcNum * restrict a,BcNum * restrict b,BcRNG * restrict rng)3815 bc_num_irand(BcNum* restrict a, BcNum* restrict b, BcRNG* restrict rng)
3816 {
3817 BcNum atemp;
3818 size_t i, len;
3819
3820 assert(a != b);
3821
3822 if (BC_ERR(BC_NUM_NEG(a))) bc_err(BC_ERR_MATH_NEGATIVE);
3823
3824 // If either of these are true, then the numbers are integers.
3825 if (BC_NUM_ZERO(a) || BC_NUM_ONE(a)) return;
3826
3827 #if BC_GCC
3828 // This is here in GCC to quiet the "maybe-uninitialized" warning.
3829 atemp.num = NULL;
3830 atemp.len = 0;
3831 #endif // BC_GCC
3832
3833 if (BC_ERR(bc_num_nonInt(a, &atemp))) bc_err(BC_ERR_MATH_NON_INTEGER);
3834
3835 assert(atemp.num != NULL);
3836 assert(atemp.len);
3837
3838 len = atemp.len - 1;
3839
3840 // Just generate a random number for each limb.
3841 for (i = 0; i < len; ++i)
3842 {
3843 b->num[i] = (BcDig) bc_rand_bounded(rng, BC_BASE_POW);
3844 }
3845
3846 // Do the last digit explicitly because the bound must be right. But only
3847 // do it if the limb does not equal 1. If it does, we have already hit the
3848 // limit.
3849 if (atemp.num[i] != 1)
3850 {
3851 b->num[i] = (BcDig) bc_rand_bounded(rng, (BcRand) atemp.num[i]);
3852 b->len = atemp.len;
3853 }
3854 // We want 1 less len in the case where we skip the last limb.
3855 else b->len = len;
3856
3857 bc_num_clean(b);
3858
3859 assert(BC_NUM_RDX_VALID(b));
3860 }
3861 #endif // BC_ENABLE_EXTRA_MATH
3862
3863 size_t
bc_num_addReq(const BcNum * a,const BcNum * b,size_t scale)3864 bc_num_addReq(const BcNum* a, const BcNum* b, size_t scale)
3865 {
3866 size_t aint, bint, ardx, brdx;
3867
3868 // Addition and subtraction require the max of the length of the two numbers
3869 // plus 1.
3870
3871 BC_UNUSED(scale);
3872
3873 ardx = BC_NUM_RDX_VAL(a);
3874 aint = bc_num_int(a);
3875 assert(aint <= a->len && ardx <= a->len);
3876
3877 brdx = BC_NUM_RDX_VAL(b);
3878 bint = bc_num_int(b);
3879 assert(bint <= b->len && brdx <= b->len);
3880
3881 ardx = BC_MAX(ardx, brdx);
3882 aint = BC_MAX(aint, bint);
3883
3884 return bc_vm_growSize(bc_vm_growSize(ardx, aint), 1);
3885 }
3886
3887 size_t
bc_num_mulReq(const BcNum * a,const BcNum * b,size_t scale)3888 bc_num_mulReq(const BcNum* a, const BcNum* b, size_t scale)
3889 {
3890 size_t max, rdx;
3891
3892 // Multiplication requires the sum of the lengths of the numbers.
3893
3894 rdx = bc_vm_growSize(BC_NUM_RDX_VAL(a), BC_NUM_RDX_VAL(b));
3895
3896 max = BC_NUM_RDX(scale);
3897
3898 max = bc_vm_growSize(BC_MAX(max, rdx), 1);
3899 rdx = bc_vm_growSize(bc_vm_growSize(bc_num_int(a), bc_num_int(b)), max);
3900
3901 return rdx;
3902 }
3903
3904 size_t
bc_num_divReq(const BcNum * a,const BcNum * b,size_t scale)3905 bc_num_divReq(const BcNum* a, const BcNum* b, size_t scale)
3906 {
3907 size_t max, rdx;
3908
3909 // Division requires the length of the dividend plus the scale.
3910
3911 rdx = bc_vm_growSize(BC_NUM_RDX_VAL(a), BC_NUM_RDX_VAL(b));
3912
3913 max = BC_NUM_RDX(scale);
3914
3915 max = bc_vm_growSize(BC_MAX(max, rdx), 1);
3916 rdx = bc_vm_growSize(bc_num_int(a), max);
3917
3918 return rdx;
3919 }
3920
3921 size_t
bc_num_powReq(const BcNum * a,const BcNum * b,size_t scale)3922 bc_num_powReq(const BcNum* a, const BcNum* b, size_t scale)
3923 {
3924 BC_UNUSED(scale);
3925 return bc_vm_growSize(bc_vm_growSize(a->len, b->len), 1);
3926 }
3927
3928 #if BC_ENABLE_EXTRA_MATH
3929 size_t
bc_num_placesReq(const BcNum * a,const BcNum * b,size_t scale)3930 bc_num_placesReq(const BcNum* a, const BcNum* b, size_t scale)
3931 {
3932 BC_UNUSED(scale);
3933 return a->len + b->len - BC_NUM_RDX_VAL(a) - BC_NUM_RDX_VAL(b);
3934 }
3935 #endif // BC_ENABLE_EXTRA_MATH
3936
3937 void
bc_num_add(BcNum * a,BcNum * b,BcNum * c,size_t scale)3938 bc_num_add(BcNum* a, BcNum* b, BcNum* c, size_t scale)
3939 {
3940 assert(BC_NUM_RDX_VALID(a));
3941 assert(BC_NUM_RDX_VALID(b));
3942 bc_num_binary(a, b, c, false, bc_num_as, bc_num_addReq(a, b, scale));
3943 }
3944
3945 void
bc_num_sub(BcNum * a,BcNum * b,BcNum * c,size_t scale)3946 bc_num_sub(BcNum* a, BcNum* b, BcNum* c, size_t scale)
3947 {
3948 assert(BC_NUM_RDX_VALID(a));
3949 assert(BC_NUM_RDX_VALID(b));
3950 bc_num_binary(a, b, c, true, bc_num_as, bc_num_addReq(a, b, scale));
3951 }
3952
3953 void
bc_num_mul(BcNum * a,BcNum * b,BcNum * c,size_t scale)3954 bc_num_mul(BcNum* a, BcNum* b, BcNum* c, size_t scale)
3955 {
3956 assert(BC_NUM_RDX_VALID(a));
3957 assert(BC_NUM_RDX_VALID(b));
3958 bc_num_binary(a, b, c, scale, bc_num_m, bc_num_mulReq(a, b, scale));
3959 }
3960
3961 void
bc_num_div(BcNum * a,BcNum * b,BcNum * c,size_t scale)3962 bc_num_div(BcNum* a, BcNum* b, BcNum* c, size_t scale)
3963 {
3964 assert(BC_NUM_RDX_VALID(a));
3965 assert(BC_NUM_RDX_VALID(b));
3966 bc_num_binary(a, b, c, scale, bc_num_d, bc_num_divReq(a, b, scale));
3967 }
3968
3969 void
bc_num_mod(BcNum * a,BcNum * b,BcNum * c,size_t scale)3970 bc_num_mod(BcNum* a, BcNum* b, BcNum* c, size_t scale)
3971 {
3972 assert(BC_NUM_RDX_VALID(a));
3973 assert(BC_NUM_RDX_VALID(b));
3974 bc_num_binary(a, b, c, scale, bc_num_rem, bc_num_divReq(a, b, scale));
3975 }
3976
3977 void
bc_num_pow(BcNum * a,BcNum * b,BcNum * c,size_t scale)3978 bc_num_pow(BcNum* a, BcNum* b, BcNum* c, size_t scale)
3979 {
3980 assert(BC_NUM_RDX_VALID(a));
3981 assert(BC_NUM_RDX_VALID(b));
3982 bc_num_binary(a, b, c, scale, bc_num_p, bc_num_powReq(a, b, scale));
3983 }
3984
3985 #if BC_ENABLE_EXTRA_MATH
3986 void
bc_num_places(BcNum * a,BcNum * b,BcNum * c,size_t scale)3987 bc_num_places(BcNum* a, BcNum* b, BcNum* c, size_t scale)
3988 {
3989 assert(BC_NUM_RDX_VALID(a));
3990 assert(BC_NUM_RDX_VALID(b));
3991 bc_num_binary(a, b, c, scale, bc_num_place, bc_num_placesReq(a, b, scale));
3992 }
3993
3994 void
bc_num_lshift(BcNum * a,BcNum * b,BcNum * c,size_t scale)3995 bc_num_lshift(BcNum* a, BcNum* b, BcNum* c, size_t scale)
3996 {
3997 assert(BC_NUM_RDX_VALID(a));
3998 assert(BC_NUM_RDX_VALID(b));
3999 bc_num_binary(a, b, c, scale, bc_num_left, bc_num_placesReq(a, b, scale));
4000 }
4001
4002 void
bc_num_rshift(BcNum * a,BcNum * b,BcNum * c,size_t scale)4003 bc_num_rshift(BcNum* a, BcNum* b, BcNum* c, size_t scale)
4004 {
4005 assert(BC_NUM_RDX_VALID(a));
4006 assert(BC_NUM_RDX_VALID(b));
4007 bc_num_binary(a, b, c, scale, bc_num_right, bc_num_placesReq(a, b, scale));
4008 }
4009 #endif // BC_ENABLE_EXTRA_MATH
4010
4011 void
bc_num_sqrt(BcNum * restrict a,BcNum * restrict b,size_t scale)4012 bc_num_sqrt(BcNum* restrict a, BcNum* restrict b, size_t scale)
4013 {
4014 BcNum num1, num2, half, f, fprime;
4015 BcNum* x0;
4016 BcNum* x1;
4017 BcNum* temp;
4018 // realscale is meant to quiet a warning on GCC about longjmp() clobbering.
4019 // This one is real.
4020 size_t pow, len, rdx, req, resscale, realscale;
4021 BcDig half_digs[1];
4022 #if BC_ENABLE_LIBRARY
4023 BcVm* vm = bcl_getspecific();
4024 #endif // BC_ENABLE_LIBRARY
4025
4026 assert(a != NULL && b != NULL && a != b);
4027
4028 if (BC_ERR(BC_NUM_NEG(a))) bc_err(BC_ERR_MATH_NEGATIVE);
4029
4030 // We want to calculate to a's scale if it is bigger so that the result will
4031 // truncate properly.
4032 if (a->scale > scale) realscale = a->scale;
4033 else realscale = scale;
4034
4035 // Set parameters for the result.
4036 len = bc_vm_growSize(bc_num_intDigits(a), 1);
4037 rdx = BC_NUM_RDX(realscale);
4038
4039 // Square root needs half of the length of the parameter.
4040 req = bc_vm_growSize(BC_MAX(rdx, BC_NUM_RDX_VAL(a)), len >> 1);
4041
4042 BC_SIG_LOCK;
4043
4044 // Unlike the binary operators, this function is the only single parameter
4045 // function and is expected to initialize the result. This means that it
4046 // expects that b is *NOT* preallocated. We allocate it here.
4047 bc_num_init(b, bc_vm_growSize(req, 1));
4048
4049 BC_SIG_UNLOCK;
4050
4051 assert(a != NULL && b != NULL && a != b);
4052 assert(a->num != NULL && b->num != NULL);
4053
4054 // Easy case.
4055 if (BC_NUM_ZERO(a))
4056 {
4057 bc_num_setToZero(b, realscale);
4058 return;
4059 }
4060
4061 // Another easy case.
4062 if (BC_NUM_ONE(a))
4063 {
4064 bc_num_one(b);
4065 bc_num_extend(b, realscale);
4066 return;
4067 }
4068
4069 // Set the parameters again.
4070 rdx = BC_NUM_RDX(realscale);
4071 rdx = BC_MAX(rdx, BC_NUM_RDX_VAL(a));
4072 len = bc_vm_growSize(a->len, rdx);
4073
4074 BC_SIG_LOCK;
4075
4076 bc_num_init(&num1, len);
4077 bc_num_init(&num2, len);
4078 bc_num_setup(&half, half_digs, sizeof(half_digs) / sizeof(BcDig));
4079
4080 // There is a division by two in the formula. We setup a number that's 1/2
4081 // so that we can use multiplication instead of heavy division.
4082 bc_num_one(&half);
4083 half.num[0] = BC_BASE_POW / 2;
4084 half.len = 1;
4085 BC_NUM_RDX_SET_NP(half, 1);
4086 half.scale = 1;
4087
4088 bc_num_init(&f, len);
4089 bc_num_init(&fprime, len);
4090
4091 BC_SETJMP_LOCKED(vm, err);
4092
4093 BC_SIG_UNLOCK;
4094
4095 // Pointers for easy switching.
4096 x0 = &num1;
4097 x1 = &num2;
4098
4099 // Start with 1.
4100 bc_num_one(x0);
4101
4102 // The power of the operand is needed for the estimate.
4103 pow = bc_num_intDigits(a);
4104
4105 // The code in this if statement calculates the initial estimate. First, if
4106 // a is less than 0, then 0 is a good estimate. Otherwise, we want something
4107 // in the same ballpark. That ballpark is pow.
4108 if (pow)
4109 {
4110 // An odd number is served by starting with 2^((pow-1)/2), and an even
4111 // number is served by starting with 6^((pow-2)/2). Why? Because math.
4112 if (pow & 1) x0->num[0] = 2;
4113 else x0->num[0] = 6;
4114
4115 pow -= 2 - (pow & 1);
4116 bc_num_shiftLeft(x0, pow / 2);
4117 }
4118
4119 // I can set the rdx here directly because neg should be false.
4120 x0->scale = x0->rdx = 0;
4121 resscale = (realscale + BC_BASE_DIGS) + 2;
4122
4123 // This is the calculation loop. This compare goes to 0 eventually as the
4124 // difference between the two numbers gets smaller than resscale.
4125 while (bc_num_cmp(x1, x0))
4126 {
4127 assert(BC_NUM_NONZERO(x0));
4128
4129 // This loop directly corresponds to the iteration in Newton's method.
4130 // If you know the formula, this loop makes sense. Go study the formula.
4131
4132 bc_num_div(a, x0, &f, resscale);
4133 bc_num_add(x0, &f, &fprime, resscale);
4134
4135 assert(BC_NUM_RDX_VALID_NP(fprime));
4136 assert(BC_NUM_RDX_VALID_NP(half));
4137
4138 bc_num_mul(&fprime, &half, x1, resscale);
4139
4140 // Switch.
4141 temp = x0;
4142 x0 = x1;
4143 x1 = temp;
4144 }
4145
4146 // Copy to the result and truncate.
4147 bc_num_copy(b, x0);
4148 if (b->scale > realscale) bc_num_truncate(b, b->scale - realscale);
4149
4150 assert(!BC_NUM_NEG(b) || BC_NUM_NONZERO(b));
4151 assert(BC_NUM_RDX_VALID(b));
4152 assert(BC_NUM_RDX_VAL(b) <= b->len || !b->len);
4153 assert(!b->len || b->num[b->len - 1] || BC_NUM_RDX_VAL(b) == b->len);
4154
4155 err:
4156 BC_SIG_MAYLOCK;
4157 bc_num_free(&fprime);
4158 bc_num_free(&f);
4159 bc_num_free(&num2);
4160 bc_num_free(&num1);
4161 BC_LONGJMP_CONT(vm);
4162 }
4163
4164 void
bc_num_divmod(BcNum * a,BcNum * b,BcNum * c,BcNum * d,size_t scale)4165 bc_num_divmod(BcNum* a, BcNum* b, BcNum* c, BcNum* d, size_t scale)
4166 {
4167 size_t ts, len;
4168 BcNum *ptr_a, num2;
4169 // This is volatile to quiet a warning on GCC about clobbering with
4170 // longjmp().
4171 volatile bool init = false;
4172 #if BC_ENABLE_LIBRARY
4173 BcVm* vm = bcl_getspecific();
4174 #endif // BC_ENABLE_LIBRARY
4175
4176 // The bulk of this function is just doing what bc_num_binary() does for the
4177 // binary operators. However, it assumes that only c and a can be equal.
4178
4179 // Set up the parameters.
4180 ts = BC_MAX(scale + b->scale, a->scale);
4181 len = bc_num_mulReq(a, b, ts);
4182
4183 assert(a != NULL && b != NULL && c != NULL && d != NULL);
4184 assert(c != d && a != d && b != d && b != c);
4185
4186 // Initialize or expand as necessary.
4187 if (c == a)
4188 {
4189 // NOLINTNEXTLINE
4190 memcpy(&num2, c, sizeof(BcNum));
4191 ptr_a = &num2;
4192
4193 BC_SIG_LOCK;
4194
4195 bc_num_init(c, len);
4196
4197 init = true;
4198
4199 BC_SETJMP_LOCKED(vm, err);
4200
4201 BC_SIG_UNLOCK;
4202 }
4203 else
4204 {
4205 ptr_a = a;
4206 bc_num_expand(c, len);
4207 }
4208
4209 // Do the quick version if possible.
4210 if (BC_NUM_NONZERO(a) && !BC_NUM_RDX_VAL(a) && !BC_NUM_RDX_VAL(b) &&
4211 b->len == 1 && !scale)
4212 {
4213 BcBigDig rem;
4214
4215 bc_num_divArray(ptr_a, (BcBigDig) b->num[0], c, &rem);
4216
4217 assert(rem < BC_BASE_POW);
4218
4219 d->num[0] = (BcDig) rem;
4220 d->len = (rem != 0);
4221 }
4222 // Do the slow method.
4223 else bc_num_r(ptr_a, b, c, d, scale, ts);
4224
4225 assert(!BC_NUM_NEG(c) || BC_NUM_NONZERO(c));
4226 assert(BC_NUM_RDX_VALID(c));
4227 assert(BC_NUM_RDX_VAL(c) <= c->len || !c->len);
4228 assert(!c->len || c->num[c->len - 1] || BC_NUM_RDX_VAL(c) == c->len);
4229 assert(!BC_NUM_NEG(d) || BC_NUM_NONZERO(d));
4230 assert(BC_NUM_RDX_VALID(d));
4231 assert(BC_NUM_RDX_VAL(d) <= d->len || !d->len);
4232 assert(!d->len || d->num[d->len - 1] || BC_NUM_RDX_VAL(d) == d->len);
4233
4234 err:
4235 // Only cleanup if we initialized.
4236 if (init)
4237 {
4238 BC_SIG_MAYLOCK;
4239 bc_num_free(&num2);
4240 BC_LONGJMP_CONT(vm);
4241 }
4242 }
4243
4244 void
bc_num_modexp(BcNum * a,BcNum * b,BcNum * c,BcNum * restrict d)4245 bc_num_modexp(BcNum* a, BcNum* b, BcNum* c, BcNum* restrict d)
4246 {
4247 BcNum base, exp, two, temp, atemp, btemp, ctemp;
4248 BcDig two_digs[2];
4249 #if BC_ENABLE_LIBRARY
4250 BcVm* vm = bcl_getspecific();
4251 #endif // BC_ENABLE_LIBRARY
4252
4253 assert(a != NULL && b != NULL && c != NULL && d != NULL);
4254 assert(a != d && b != d && c != d);
4255
4256 if (BC_ERR(BC_NUM_ZERO(c))) bc_err(BC_ERR_MATH_DIVIDE_BY_ZERO);
4257 if (BC_ERR(BC_NUM_NEG(b))) bc_err(BC_ERR_MATH_NEGATIVE);
4258
4259 #if BC_DEBUG || BC_GCC
4260 // This is entirely for quieting a useless scan-build error.
4261 btemp.len = 0;
4262 ctemp.len = 0;
4263 #endif // BC_DEBUG || BC_GCC
4264
4265 // Eliminate fractional parts that are zero or error if they are not zero.
4266 if (BC_ERR(bc_num_nonInt(a, &atemp) || bc_num_nonInt(b, &btemp) ||
4267 bc_num_nonInt(c, &ctemp)))
4268 {
4269 bc_err(BC_ERR_MATH_NON_INTEGER);
4270 }
4271
4272 bc_num_expand(d, ctemp.len);
4273
4274 BC_SIG_LOCK;
4275
4276 bc_num_init(&base, ctemp.len);
4277 bc_num_setup(&two, two_digs, sizeof(two_digs) / sizeof(BcDig));
4278 bc_num_init(&temp, btemp.len + 1);
4279 bc_num_createCopy(&exp, &btemp);
4280
4281 BC_SETJMP_LOCKED(vm, err);
4282
4283 BC_SIG_UNLOCK;
4284
4285 bc_num_one(&two);
4286 two.num[0] = 2;
4287 bc_num_one(d);
4288
4289 // We already checked for 0.
4290 bc_num_rem(&atemp, &ctemp, &base, 0);
4291
4292 // If you know the algorithm I used, the memory-efficient method, then this
4293 // loop should be self-explanatory because it is the calculation loop.
4294 while (BC_NUM_NONZERO(&exp))
4295 {
4296 // Num two cannot be 0, so no errors.
4297 bc_num_divmod(&exp, &two, &exp, &temp, 0);
4298
4299 if (BC_NUM_ONE(&temp) && !BC_NUM_NEG_NP(temp))
4300 {
4301 assert(BC_NUM_RDX_VALID(d));
4302 assert(BC_NUM_RDX_VALID_NP(base));
4303
4304 bc_num_mul(d, &base, &temp, 0);
4305
4306 // We already checked for 0.
4307 bc_num_rem(&temp, &ctemp, d, 0);
4308 }
4309
4310 assert(BC_NUM_RDX_VALID_NP(base));
4311
4312 bc_num_mul(&base, &base, &temp, 0);
4313
4314 // We already checked for 0.
4315 bc_num_rem(&temp, &ctemp, &base, 0);
4316 }
4317
4318 err:
4319 BC_SIG_MAYLOCK;
4320 bc_num_free(&exp);
4321 bc_num_free(&temp);
4322 bc_num_free(&base);
4323 BC_LONGJMP_CONT(vm);
4324 assert(!BC_NUM_NEG(d) || d->len);
4325 assert(BC_NUM_RDX_VALID(d));
4326 assert(!d->len || d->num[d->len - 1] || BC_NUM_RDX_VAL(d) == d->len);
4327 }
4328
4329 #if BC_DEBUG_CODE
4330 void
bc_num_printDebug(const BcNum * n,const char * name,bool emptyline)4331 bc_num_printDebug(const BcNum* n, const char* name, bool emptyline)
4332 {
4333 bc_file_puts(&vm->fout, bc_flush_none, name);
4334 bc_file_puts(&vm->fout, bc_flush_none, ": ");
4335 bc_num_printDecimal(n, true);
4336 bc_file_putchar(&vm->fout, bc_flush_err, '\n');
4337 if (emptyline) bc_file_putchar(&vm->fout, bc_flush_err, '\n');
4338 vm->nchars = 0;
4339 }
4340
4341 void
bc_num_printDigs(const BcDig * n,size_t len,bool emptyline)4342 bc_num_printDigs(const BcDig* n, size_t len, bool emptyline)
4343 {
4344 size_t i;
4345
4346 for (i = len - 1; i < len; --i)
4347 {
4348 bc_file_printf(&vm->fout, " %lu", (unsigned long) n[i]);
4349 }
4350
4351 bc_file_putchar(&vm->fout, bc_flush_err, '\n');
4352 if (emptyline) bc_file_putchar(&vm->fout, bc_flush_err, '\n');
4353 vm->nchars = 0;
4354 }
4355
4356 void
bc_num_printWithDigs(const BcNum * n,const char * name,bool emptyline)4357 bc_num_printWithDigs(const BcNum* n, const char* name, bool emptyline)
4358 {
4359 bc_file_puts(&vm->fout, bc_flush_none, name);
4360 bc_file_printf(&vm->fout, " len: %zu, rdx: %zu, scale: %zu\n", name, n->len,
4361 BC_NUM_RDX_VAL(n), n->scale);
4362 bc_num_printDigs(n->num, n->len, emptyline);
4363 }
4364
4365 void
bc_num_dump(const char * varname,const BcNum * n)4366 bc_num_dump(const char* varname, const BcNum* n)
4367 {
4368 ulong i, scale = n->scale;
4369
4370 bc_file_printf(&vm->ferr, "\n%s = %s", varname,
4371 n->len ? (BC_NUM_NEG(n) ? "-" : "+") : "0 ");
4372
4373 for (i = n->len - 1; i < n->len; --i)
4374 {
4375 if (i + 1 == BC_NUM_RDX_VAL(n))
4376 {
4377 bc_file_puts(&vm->ferr, bc_flush_none, ". ");
4378 }
4379
4380 if (scale / BC_BASE_DIGS != BC_NUM_RDX_VAL(n) - i - 1)
4381 {
4382 bc_file_printf(&vm->ferr, "%lu ", (unsigned long) n->num[i]);
4383 }
4384 else
4385 {
4386 int mod = scale % BC_BASE_DIGS;
4387 int d = BC_BASE_DIGS - mod;
4388 BcDig div;
4389
4390 if (mod != 0)
4391 {
4392 div = n->num[i] / ((BcDig) bc_num_pow10[(ulong) d]);
4393 bc_file_printf(&vm->ferr, "%lu", (unsigned long) div);
4394 }
4395
4396 div = n->num[i] % ((BcDig) bc_num_pow10[(ulong) d]);
4397 bc_file_printf(&vm->ferr, " ' %lu ", (unsigned long) div);
4398 }
4399 }
4400
4401 bc_file_printf(&vm->ferr, "(%zu | %zu.%zu / %zu) %lu\n", n->scale, n->len,
4402 BC_NUM_RDX_VAL(n), n->cap, (unsigned long) (void*) n->num);
4403
4404 bc_file_flush(&vm->ferr, bc_flush_err);
4405 }
4406 #endif // BC_DEBUG_CODE
4407