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