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