denyhosts/clamav/libclamav/tomsfastmath/bit/fp_div_2d.c

80 lines
1.5 KiB
C

/* TomsFastMath, a fast ISO C bignum library.
*
* This project is meant to fill in where LibTomMath
* falls short. That is speed ;-)
*
* This project is public domain and free for all purposes.
*
* Tom St Denis, tomstdenis@gmail.com
*/
#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);
}
}
/* $Source$ */
/* $Revision$ */
/* $Date$ */