00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063 CLASS_TYPE
00064 ADD_HELPER(small_type us, int unb, int und,
00065 const sc_digit *ud,
00066 small_type vs, int vnb, int vnd,
00067 const sc_digit *vd)
00068 {
00069
00070 und = vec_skip_leading_zeros(und, ud);
00071 vnd = vec_skip_leading_zeros(vnd, vd);
00072
00073 int nb = sc_max(unb, vnb);
00074 int nd = sc_max(und, vnd) + 1;
00075
00076 #ifdef SC_MAX_NBITS
00077 test_bound(nb);
00078 sc_digit d[MAX_NDIGITS];
00079 #else
00080 sc_digit *d = new sc_digit[nd];
00081 #endif
00082
00083 d[nd - 1] = d[nd - 2] = 0;
00084
00085
00086 if (us == vs) {
00087
00088 ++nb;
00089
00090 if ((und == 1) && (vnd == 1)) {
00091 sc_digit carry = (*ud) + (*vd);
00092 d[0] = carry & DIGIT_MASK;
00093 d[1] = carry >> BITS_PER_DIGIT;
00094 }
00095
00096 else if (und >= vnd)
00097 vec_add(und, ud, vnd, vd, d);
00098
00099 else
00100 vec_add(vnd, vd, und, ud, d);
00101
00102 }
00103
00104
00105 else {
00106
00107 int cmp_res = vec_cmp(und, ud, vnd, vd);
00108
00109 if (cmp_res == 0)
00110 return CLASS_TYPE();
00111
00112 if (cmp_res > 0) {
00113
00114 if ((und == 1) && (vnd == 1))
00115 d[0] = (*ud) - (*vd);
00116 else
00117 vec_sub(und, ud, vnd, vd, d);
00118
00119 }
00120 else {
00121
00122 us = -us;
00123
00124 if ((und == 1) && (vnd == 1))
00125 d[0] = (*vd) - (*ud);
00126 else
00127 vec_sub(vnd, vd, und, ud, d);
00128
00129 }
00130 }
00131
00132 return CLASS_TYPE(us, nb, nd, d);
00133
00134 }
00135
00136
00137
00138
00139
00140
00141
00142 CLASS_TYPE
00143 MUL_HELPER(small_type s,
00144 int unb, int und,
00145 const sc_digit *ud,
00146 int vnb, int vnd,
00147 const sc_digit *vd)
00148 {
00149
00150 und = vec_skip_leading_zeros(und, ud);
00151 vnd = vec_skip_leading_zeros(vnd, vd);
00152
00153 int nb = unb + vnb;
00154 int nd = und + vnd;
00155
00156 #ifdef SC_MAX_NBITS
00157 test_bound(nb);
00158 sc_digit d[MAX_NDIGITS];
00159 #else
00160 sc_digit *d = new sc_digit[nd];
00161 #endif
00162
00163 vec_zero(nd, d);
00164
00165 sc_digit ud0 = (*ud);
00166 sc_digit vd0 = (*vd);
00167
00168 if ((vnd == 1) && (vd0 == 1))
00169 vec_copy(und, d, ud);
00170
00171 else if ((und == 1) && (ud0 == 1))
00172 vec_copy(vnd, d, vd);
00173
00174 else if ((und == 1) && (vnd == 1) &&
00175 (ud0 < HALF_DIGIT_RADIX) && (vd0 < HALF_DIGIT_RADIX))
00176 d[0] = ud0 * vd0;
00177
00178 else if ((und == 1) && (ud0 < HALF_DIGIT_RADIX))
00179 vec_mul_small(vnd, vd, ud0, d);
00180
00181 else if ((vnd == 1) && (vd0 < HALF_DIGIT_RADIX))
00182 vec_mul_small(und, ud, vd0, d);
00183
00184 else if (vnd < und)
00185 vec_mul(und, ud, vnd, vd, d);
00186
00187 else
00188 vec_mul(vnd, vd, und, ud, d);
00189
00190 return CLASS_TYPE(s, nb, nd, d);
00191
00192 }
00193
00194
00195
00196
00197
00198
00199
00200 CLASS_TYPE
00201 DIV_HELPER(small_type s,
00202 int unb, int und,
00203 const sc_digit *ud,
00204 int vnb, int vnd,
00205 const sc_digit *vd)
00206 {
00207
00208 und = vec_skip_leading_zeros(und, ud);
00209 vnd = vec_skip_leading_zeros(vnd, vd);
00210
00211 int cmp_res = vec_cmp(und, ud, vnd, vd);
00212
00213
00214 if (cmp_res < 0)
00215 return CLASS_TYPE();
00216
00217
00218 int nd = sc_max(und, vnd) + 1;
00219
00220 #ifdef SC_MAX_NBITS
00221 sc_digit d[MAX_NDIGITS + 1];
00222 #else
00223 sc_digit *d = new sc_digit[nd];
00224 #endif
00225
00226 vec_zero(nd, d);
00227
00228 sc_digit vd0 = (*vd);
00229
00230
00231 if (cmp_res == 0)
00232 d[0] = 1;
00233
00234
00235
00236 else if ((vnd == 1) && (vd0 == 1))
00237 vec_copy(und, d, ud);
00238
00239 else if ((vnd == 1) && (und == 1))
00240 d[0] = (*ud) / vd0;
00241
00242 else if ((vnd == 1) && (vd0 < HALF_DIGIT_RADIX))
00243 vec_div_small(und, ud, vd0, d);
00244
00245 else
00246 vec_div_large(und, ud, vnd, vd, d);
00247
00248 return CLASS_TYPE(s, sc_max(unb, vnb), nd - 1, d);
00249
00250 }
00251
00252
00253
00254
00255
00256
00257
00258 CLASS_TYPE
00259 MOD_HELPER(small_type us,
00260 int unb, int und,
00261 const sc_digit *ud,
00262 int vnb, int vnd,
00263 const sc_digit *vd)
00264 {
00265
00266 und = vec_skip_leading_zeros(und, ud);
00267 vnd = vec_skip_leading_zeros(vnd, vd);
00268
00269 int cmp_res = vec_cmp(und, ud, vnd, vd);
00270
00271
00272 if (cmp_res == 0)
00273 return CLASS_TYPE();
00274
00275 sc_digit vd0 = (*vd);
00276
00277 if ((cmp_res > 0) && (vnd == 1) && (vd0 == 1))
00278 return CLASS_TYPE();
00279
00280
00281 int nd = sc_max(und, vnd) + 1;
00282
00283 #ifdef SC_MAX_NBITS
00284 sc_digit d[MAX_NDIGITS + 1];
00285 #else
00286 sc_digit *d = new sc_digit[nd];
00287 #endif
00288
00289 vec_zero(nd, d);
00290
00291
00292 if (cmp_res < 0)
00293 vec_copy(und, d, ud);
00294
00295
00296
00297 else if ((vnd == 1) && (und == 1))
00298 d[0] = (*ud) % vd0;
00299
00300 else if ((vnd == 1) && (vd0 < HALF_DIGIT_RADIX))
00301 d[0] = vec_rem_small(und, ud, vd0);
00302
00303 else
00304 vec_rem_large(und, ud, vnd, vd, d);
00305
00306 us = check_for_zero(us, nd - 1, d);
00307
00308 if (us == SC_ZERO)
00309 return CLASS_TYPE();
00310 else
00311 return CLASS_TYPE(us, sc_min(unb, vnb), nd - 1, d);
00312
00313 }
00314
00315
00316
00317
00318
00319
00320
00321 CLASS_TYPE
00322 AND_HELPER(small_type us,
00323 int unb, int und,
00324 const sc_digit *ud,
00325 small_type vs,
00326 int vnb, int vnd,
00327 const sc_digit *vd)
00328 {
00329
00330 int nb = sc_max(unb, vnb);
00331 int nd = sc_max(und, vnd);
00332
00333 #ifdef SC_MAX_NBITS
00334 sc_digit dbegin[MAX_NDIGITS];
00335 #else
00336 sc_digit *dbegin = new sc_digit[nd];
00337 #endif
00338
00339 sc_digit *d = dbegin;
00340
00341 register const sc_digit *x;
00342 register const sc_digit *y;
00343 int xnd;
00344 int ynd;
00345 small_type xs;
00346 small_type ys;
00347
00348 if (und >= vnd) {
00349 x = ud;
00350 y = vd;
00351 xnd = und;
00352 ynd = vnd;
00353 xs = us;
00354 ys = vs;
00355 }
00356 else {
00357 y = ud;
00358 x = vd;
00359 ynd = und;
00360 xnd = vnd;
00361 ys = us;
00362 xs = vs;
00363 }
00364
00365 const sc_digit *xend = (x + xnd);
00366 const sc_digit *yend = (y + ynd);
00367
00368
00369
00370 small_type s = mul_signs(xs, ys);
00371
00372 if (s > 0) {
00373
00374 if (xs > 0) {
00375
00376 while (y < yend)
00377 (*d++) = (*x++) & (*y++);
00378
00379 while (x++ < xend)
00380 (*d++) = 0;
00381
00382 }
00383 else {
00384
00385 register sc_digit xcarry = 1;
00386 register sc_digit ycarry = 1;
00387
00388 while (y < yend) {
00389 xcarry += (~(*x++) & DIGIT_MASK);
00390 ycarry += (~(*y++) & DIGIT_MASK);
00391 (*d++) = (xcarry & ycarry) & DIGIT_MASK;
00392 xcarry >>= BITS_PER_DIGIT;
00393 ycarry >>= BITS_PER_DIGIT;
00394 }
00395
00396 while (x < xend) {
00397 xcarry += (~(*x++) & DIGIT_MASK);
00398 ycarry += DIGIT_MASK;
00399 (*d++) = (xcarry & ycarry) & DIGIT_MASK;
00400 xcarry >>= BITS_PER_DIGIT;
00401 ycarry >>= BITS_PER_DIGIT;
00402 }
00403
00404 }
00405 }
00406 else {
00407
00408 if (xs > 0) {
00409
00410 register sc_digit ycarry = 1;
00411
00412 while (y < yend) {
00413 ycarry += (~(*y++) & DIGIT_MASK);
00414 (*d++) = ((*x++) & ycarry) & DIGIT_MASK;
00415 ycarry >>= BITS_PER_DIGIT;
00416 }
00417
00418 while (x < xend) {
00419 ycarry += DIGIT_MASK;
00420 (*d++) = ((*x++) & ycarry) & DIGIT_MASK;
00421 ycarry >>= BITS_PER_DIGIT;
00422 }
00423
00424 }
00425 else {
00426
00427 register sc_digit xcarry = 1;
00428
00429 while (y < yend) {
00430 xcarry += (~(*x++) & DIGIT_MASK);
00431 (*d++) = (xcarry & (*y++)) & DIGIT_MASK;
00432 xcarry >>= BITS_PER_DIGIT;
00433 }
00434
00435 while (x++ < xend)
00436 (*d++) = 0;
00437
00438 }
00439 }
00440
00441 s = convert_signed_2C_to_SM(nb, nd, dbegin);
00442
00443 return CLASS_TYPE(s, nb, nd, dbegin);
00444
00445 }
00446
00447
00448
00449
00450
00451
00452
00453 CLASS_TYPE
00454 OR_HELPER(small_type us,
00455 int unb, int und,
00456 const sc_digit *ud,
00457 small_type vs,
00458 int vnb, int vnd,
00459 const sc_digit *vd)
00460 {
00461
00462 int nb = sc_max(unb, vnb);
00463 int nd = sc_max(und, vnd);
00464
00465 #ifdef SC_MAX_NBITS
00466 sc_digit dbegin[MAX_NDIGITS];
00467 #else
00468 sc_digit *dbegin = new sc_digit[nd];
00469 #endif
00470
00471 sc_digit *d = dbegin;
00472
00473 register const sc_digit *x;
00474 register const sc_digit *y;
00475 int xnd;
00476 int ynd;
00477 small_type xs;
00478 small_type ys;
00479
00480 if (und >= vnd) {
00481 x = ud;
00482 y = vd;
00483 xnd = und;
00484 ynd = vnd;
00485 xs = us;
00486 ys = vs;
00487 }
00488 else {
00489 y = ud;
00490 x = vd;
00491 ynd = und;
00492 xnd = vnd;
00493 ys = us;
00494 xs = vs;
00495 }
00496
00497 const sc_digit *xend = (x + xnd);
00498 const sc_digit *yend = (y + ynd);
00499
00500
00501
00502 small_type s = mul_signs(xs, ys);
00503
00504 if (s > 0) {
00505
00506 if (xs > 0) {
00507
00508 while (y < yend)
00509 (*d++) = (*x++) | (*y++);
00510
00511 while (x < xend)
00512 (*d++) = (*x++);
00513
00514 }
00515 else {
00516
00517 register sc_digit xcarry = 1;
00518 register sc_digit ycarry = 1;
00519
00520 while (y < yend) {
00521 xcarry += (~(*x++) & DIGIT_MASK);
00522 ycarry += (~(*y++) & DIGIT_MASK);
00523 (*d++) = (xcarry | ycarry) & DIGIT_MASK;
00524 xcarry >>= BITS_PER_DIGIT;
00525 ycarry >>= BITS_PER_DIGIT;
00526 }
00527
00528 while (x < xend) {
00529 xcarry += (~(*x++) & DIGIT_MASK);
00530 ycarry += DIGIT_MASK;
00531 (*d++) = (xcarry | ycarry) & DIGIT_MASK;
00532 xcarry >>= BITS_PER_DIGIT;
00533 ycarry >>= BITS_PER_DIGIT;
00534 }
00535
00536 }
00537
00538 }
00539 else {
00540
00541 if (xs > 0) {
00542
00543 register sc_digit ycarry = 1;
00544
00545 while (y < yend) {
00546 ycarry += (~(*y++) & DIGIT_MASK);
00547 (*d++) = ((*x++) | ycarry) & DIGIT_MASK;
00548 ycarry >>= BITS_PER_DIGIT;
00549 }
00550
00551 while (x < xend) {
00552 ycarry += DIGIT_MASK;
00553 (*d++) = ((*x++) | ycarry) & DIGIT_MASK;
00554 ycarry >>= BITS_PER_DIGIT;
00555 }
00556
00557 }
00558 else {
00559
00560 register sc_digit xcarry = 1;
00561
00562 while (y < yend) {
00563 xcarry += (~(*x++) & DIGIT_MASK);
00564 (*d++) = (xcarry | (*y++)) & DIGIT_MASK;
00565 xcarry >>= BITS_PER_DIGIT;
00566 }
00567
00568 while (x < xend) {
00569 xcarry += (~(*x++) & DIGIT_MASK);
00570 (*d++) = xcarry & DIGIT_MASK;
00571 xcarry >>= BITS_PER_DIGIT;
00572 }
00573 }
00574
00575 }
00576
00577 s = convert_signed_2C_to_SM(nb, nd, dbegin);
00578
00579 return CLASS_TYPE(s, nb, nd, dbegin);
00580
00581 }
00582
00583
00584
00585
00586
00587
00588
00589 CLASS_TYPE
00590 XOR_HELPER(small_type us,
00591 int unb, int und,
00592 const sc_digit *ud,
00593 small_type vs,
00594 int vnb, int vnd,
00595 const sc_digit *vd)
00596 {
00597
00598 int nb = sc_max(unb, vnb);
00599 int nd = sc_max(und, vnd);
00600
00601 #ifdef SC_MAX_NBITS
00602 sc_digit dbegin[MAX_NDIGITS];
00603 #else
00604 sc_digit *dbegin = new sc_digit[nd];
00605 #endif
00606
00607 sc_digit *d = dbegin;
00608
00609 register const sc_digit *x;
00610 register const sc_digit *y;
00611 int xnd;
00612 int ynd;
00613 small_type xs;
00614 small_type ys;
00615
00616 if (und >= vnd) {
00617 x = ud;
00618 y = vd;
00619 xnd = und;
00620 ynd = vnd;
00621 xs = us;
00622 ys = vs;
00623 }
00624 else {
00625 y = ud;
00626 x = vd;
00627 ynd = und;
00628 xnd = vnd;
00629 ys = us;
00630 xs = vs;
00631 }
00632
00633 const sc_digit *xend = (x + xnd);
00634 const sc_digit *yend = (y + ynd);
00635
00636
00637
00638 small_type s = mul_signs(xs, ys);
00639
00640 if (s > 0) {
00641
00642 if (xs > 0) {
00643
00644 while (y < yend)
00645 (*d++) = ((*x++) ^ (*y++)) & DIGIT_MASK;
00646
00647 while (x < xend)
00648 (*d++) = (*x++);
00649
00650 }
00651 else {
00652
00653 register sc_digit xcarry = 1;
00654 register sc_digit ycarry = 1;
00655
00656 while (y < yend) {
00657 xcarry += (~(*x++) & DIGIT_MASK);
00658 ycarry += (~(*y++) & DIGIT_MASK);
00659 (*d++) = (xcarry ^ ycarry) & DIGIT_MASK;
00660 xcarry >>= BITS_PER_DIGIT;
00661 ycarry >>= BITS_PER_DIGIT;
00662 }
00663
00664 while (x < xend) {
00665 xcarry += (~(*x++) & DIGIT_MASK);
00666 ycarry += DIGIT_MASK;
00667 (*d++) = (xcarry ^ ycarry) & DIGIT_MASK;
00668 xcarry >>= BITS_PER_DIGIT;
00669 ycarry >>= BITS_PER_DIGIT;
00670 }
00671
00672 }
00673 }
00674 else {
00675
00676 if (xs > 0) {
00677
00678 register sc_digit ycarry = 1;
00679
00680 while (y < yend) {
00681 ycarry += (~(*y++) & DIGIT_MASK);
00682 (*d++) = ((*x++) ^ ycarry) & DIGIT_MASK;
00683 ycarry >>= BITS_PER_DIGIT;
00684 }
00685
00686 while (x < xend) {
00687 ycarry += DIGIT_MASK;
00688 (*d++) = ((*x++) ^ ycarry) & DIGIT_MASK;
00689 ycarry >>= BITS_PER_DIGIT;
00690 }
00691
00692 }
00693 else {
00694
00695 register sc_digit xcarry = 1;
00696
00697 while (y < yend) {
00698 xcarry += (~(*x++) & DIGIT_MASK);
00699 (*d++) = (xcarry ^ (*y++)) & DIGIT_MASK;
00700 xcarry >>= BITS_PER_DIGIT;
00701 }
00702
00703 while (x < xend) {
00704 xcarry += (~(*x++) & DIGIT_MASK);
00705 (*d++) = xcarry & DIGIT_MASK;
00706 xcarry >>= BITS_PER_DIGIT;
00707 }
00708 }
00709 }
00710
00711 s = convert_signed_2C_to_SM(nb, nd, dbegin);
00712
00713 return CLASS_TYPE(s, nb, nd, dbegin);
00714
00715 }
00716
00717
00718