/src/bit/fp_div_2d.c
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}