80 lines
1.6 KiB
C
80 lines
1.6 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 "bignum_fast.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: /cvs/libtom/tomsfastmath/src/bit/fp_div_2d.c,v $ */
|
|
/* $Revision: 1.1 $ */
|
|
/* $Date: 2006/12/31 21:25:53 $ */
|