PageRenderTime 24ms CodeModel.GetById 20ms app.highlight 2ms RepoModel.GetById 1ms app.codeStats 0ms

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