bn_mp_div_d.cGo to the documentation of this file.00001 #include <tommath.h> 00002 #ifdef BN_MP_DIV_D_C 00003 /* LibTomMath, multiple-precision integer library -- Tom St Denis 00004 * 00005 * LibTomMath is a library that provides multiple-precision 00006 * integer arithmetic as well as number theoretic functionality. 00007 * 00008 * The library was designed directly after the MPI library by 00009 * Michael Fromberger but has been written from scratch with 00010 * additional optimizations in place. 00011 * 00012 * The library is free for all purposes without any express 00013 * guarantee it works. 00014 * 00015 * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com 00016 */ 00017 00018 static int s_is_power_of_two(mp_digit b, int *p) 00019 { 00020 int x; 00021 00022 /* quick out - if (b & (b-1)) isn't zero, b isn't a power of two */ 00023 if ((b & (b-1)) != 0) { 00024 return 0; 00025 } 00026 for (x = 1; x < DIGIT_BIT; x++) { 00027 if (b == (((mp_digit)1)<<x)) { 00028 *p = x; 00029 return 1; 00030 } 00031 } 00032 return 0; 00033 } 00034 00035 /* single digit division (based on routine from MPI) */ 00036 int mp_div_d (mp_int * a, mp_digit b, mp_int * c, mp_digit * d) 00037 { 00038 mp_int q; 00039 mp_word w; 00040 mp_digit t; 00041 int res, ix; 00042 00043 /* cannot divide by zero */ 00044 if (b == 0) { 00045 return MP_VAL; 00046 } 00047 00048 /* quick outs */ 00049 if (b == 1 || mp_iszero(a) == 1) { 00050 if (d != NULL) { 00051 *d = 0; 00052 } 00053 if (c != NULL) { 00054 return mp_copy(a, c); 00055 } 00056 return MP_OKAY; 00057 } 00058 00059 /* power of two ? */ 00060 if (s_is_power_of_two(b, &ix) == 1) { 00061 if (d != NULL) { 00062 *d = a->dp[0] & ((((mp_digit)1)<<ix) - 1); 00063 } 00064 if (c != NULL) { 00065 return mp_div_2d(a, ix, c, NULL); 00066 } 00067 return MP_OKAY; 00068 } 00069 00070 #ifdef BN_MP_DIV_3_C 00071 /* three? */ 00072 if (b == 3) { 00073 return mp_div_3(a, c, d); 00074 } 00075 #endif 00076 00077 /* no easy answer [c'est la vie]. Just division */ 00078 if ((res = mp_init_size(&q, a->used)) != MP_OKAY) { 00079 return res; 00080 } 00081 00082 q.used = a->used; 00083 q.sign = a->sign; 00084 w = 0; 00085 for (ix = a->used - 1; ix >= 0; ix--) { 00086 w = (w << ((mp_word)DIGIT_BIT)) | ((mp_word)a->dp[ix]); 00087 00088 if (w >= b) { 00089 t = (mp_digit)(w / b); 00090 w -= ((mp_word)t) * ((mp_word)b); 00091 } else { 00092 t = 0; 00093 } 00094 q.dp[ix] = (mp_digit)t; 00095 } 00096 00097 if (d != NULL) { 00098 *d = (mp_digit)w; 00099 } 00100 00101 if (c != NULL) { 00102 mp_clamp(&q); 00103 mp_exch(&q, c); 00104 } 00105 mp_clear(&q); 00106 00107 return res; 00108 } 00109 00110 #endif 00111 00112 /* $Source: /cvsroot/tcl/libtommath/bn_mp_div_d.c,v $ */ 00113 /* $Revision: 1.3 $ */ 00114 /* $Date: 2006/12/01 05:47:47 $ */
Generated on Wed Mar 12 12:18:24 2008 by 1.5.1 |