/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
- /* TomsFastMath, a fast ISO C bignum library. -- Tom St Denis */
- /* SPDX-License-Identifier: Unlicense */
- #include <tfm_private.h>
- /* c = a / 2**b */
- void fp_div_2d(fp_int *a, int b, fp_int *c, fp_int *d)
- {
- fp_digit D, r, rr;
- int x;
- fp_int t;
- /* if the shift count is <= 0 then we do no work */
- if (b <= 0) {
- fp_copy (a, c);
- if (d != NULL) {
- fp_zero (d);
- }
- return;
- }
- fp_init(&t);
- /* get the remainder */
- if (d != NULL) {
- fp_mod_2d (a, b, &t);
- }
- /* copy */
- fp_copy(a, c);
- /* shift by as many digits in the bit count */
- if (b >= (int)DIGIT_BIT) {
- fp_rshd (c, b / DIGIT_BIT);
- }
- /* shift any bit count < DIGIT_BIT */
- D = (fp_digit) (b % DIGIT_BIT);
- if (D != 0) {
- register fp_digit *tmpc, mask, shift;
- /* mask */
- mask = (((fp_digit)1) << D) - 1;
- /* shift for lsb */
- shift = DIGIT_BIT - D;
- /* alias */
- tmpc = c->dp + (c->used - 1);
- /* carry */
- r = 0;
- for (x = c->used - 1; x >= 0; x--) {
- /* get the lower bits of this word in a temp */
- rr = *tmpc & mask;
- /* shift the current word and mix in the carry bits from the previous word */
- *tmpc = (*tmpc >> D) | (r << shift);
- --tmpc;
- /* set the carry to the carry bits of the current word found above */
- r = rr;
- }
- }
- fp_clamp (c);
- if (d != NULL) {
- fp_copy (&t, d);
- }
- }