Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/bc/src/num.c
39536 views
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
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
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
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
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
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
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
142
bc_num_zero(BcNum* restrict n)
143
{
144
bc_num_setToZero(n, 0);
145
}
146
147
void
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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 <[email protected]> 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
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
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
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
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
3440
bc_num_clear(BcNum* restrict n)
3441
{
3442
n->num = NULL;
3443
n->cap = 0;
3444
}
3445
3446
void
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
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
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
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
3494
bc_num_scale(const BcNum* restrict n)
3495
{
3496
return n->scale;
3497
}
3498
3499
size_t
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
4523