/src/bit/fp_div_2d.c

http://github.com/libtom/tomsfastmath · C · 68 lines · 40 code · 13 blank · 15 comment · 11 complexity · b0ebe927b3f3efa2f8f92de1650431c5 MD5 · raw file

  1. /* TomsFastMath, a fast ISO C bignum library. -- Tom St Denis */
  2. /* SPDX-License-Identifier: Unlicense */
  3. #include <tfm_private.h>
  4. /* c = a / 2**b */
  5. void fp_div_2d(fp_int *a, int b, fp_int *c, fp_int *d)
  6. {
  7. fp_digit D, r, rr;
  8. int x;
  9. fp_int t;
  10. /* if the shift count is <= 0 then we do no work */
  11. if (b <= 0) {
  12. fp_copy (a, c);
  13. if (d != NULL) {
  14. fp_zero (d);
  15. }
  16. return;
  17. }
  18. fp_init(&t);
  19. /* get the remainder */
  20. if (d != NULL) {
  21. fp_mod_2d (a, b, &t);
  22. }
  23. /* copy */
  24. fp_copy(a, c);
  25. /* shift by as many digits in the bit count */
  26. if (b >= (int)DIGIT_BIT) {
  27. fp_rshd (c, b / DIGIT_BIT);
  28. }
  29. /* shift any bit count < DIGIT_BIT */
  30. D = (fp_digit) (b % DIGIT_BIT);
  31. if (D != 0) {
  32. register fp_digit *tmpc, mask, shift;
  33. /* mask */
  34. mask = (((fp_digit)1) << D) - 1;
  35. /* shift for lsb */
  36. shift = DIGIT_BIT - D;
  37. /* alias */
  38. tmpc = c->dp + (c->used - 1);
  39. /* carry */
  40. r = 0;
  41. for (x = c->used - 1; x >= 0; x--) {
  42. /* get the lower bits of this word in a temp */
  43. rr = *tmpc & mask;
  44. /* shift the current word and mix in the carry bits from the previous word */
  45. *tmpc = (*tmpc >> D) | (r << shift);
  46. --tmpc;
  47. /* set the carry to the carry bits of the current word found above */
  48. r = rr;
  49. }
  50. }
  51. fp_clamp (c);
  52. if (d != NULL) {
  53. fp_copy (&t, d);
  54. }
  55. }