メインページ   モジュール   データ構造   ファイル一覧   データフィールド   グローバル  

shift.c

解説を見る。
00001 #include "multiprec.h"
00002 #include <string.h>
00003 
00033 size_t
00034 ymp_rshiftabs(digit_t *result, const digit_t *source, size_t len, size_t width)
00035 {
00036   register size_t i;
00037   size_t n_digits = width / DIGIT_BIT;
00038   size_t n_bits = width % DIGIT_BIT;
00039   digit_t prev;
00040 
00041   if (len <= n_digits) return 0;
00042 
00043   i=len; prev=0;
00044   while (i-- > n_digits)
00045     {
00046       double_digit_t tmp = LOW_DIGIT_TO_HIGH_DIGIT((double_digit_t)prev);
00047       prev = source[i];
00048       tmp += source[i];
00049       result[i-n_digits] = LOW_DIGIT(tmp >> n_bits);
00050     }
00051 
00052 
00053   /* 要素数の調整 */ 
00054   len -= n_digits;                /* 今、len > n_digits */
00055   if (result[len-1]==0) --len;
00056 
00057   return len;
00058 }
00059 
00075 size_t
00076 ymp_lshiftabs(digit_t *result, const digit_t *source, size_t len, size_t width)
00077 {
00078   register size_t i;
00079   size_t n_digits = width / DIGIT_BIT;
00080   size_t n_bits = width % DIGIT_BIT;
00081   double_digit_t tmp;
00082 
00083   if (len == 0) return 0;
00084   
00085   i = len; tmp = source[--i];
00086   tmp <<= n_bits;
00087   if (HIGH_DIGIT(tmp)) result[len++ + n_digits] = HIGH_DIGIT(tmp);
00088 
00089   tmp = source[i];
00090   while (i-- > 0)
00091     {
00092       tmp = LOW_DIGIT_TO_HIGH_DIGIT(tmp);
00093       tmp += source[i];
00094       result[i+n_digits+1] = HIGH_DIGIT(tmp << n_bits);
00095       tmp = source[i];
00096     }
00097   result[n_digits] = source[0] << n_bits;
00098 
00099   i = n_digits;
00100   while (i-- > 0) result[i] = 0;
00101   
00102   return len + n_digits;
00103 }
00104 
00105 
00119 size_t 
00120 ymp_modabs_2exp(digit_t *result, const digit_t *self, size_t len, size_t pow)
00121 {
00122   size_t n_digits = pow / DIGIT_BIT;
00123   size_t n_bits = pow % DIGIT_BIT;
00124 
00125   if (n_digits < len)
00126     {
00127       len = n_digits;
00128       if (n_bits)
00129         {
00130           result[n_digits] = self[n_digits] & ( (1u << n_bits) - 1u );
00131           ++n_digits;
00132         }
00133     }
00134   else if (n_digits > len)
00135     {
00136       n_digits = len;
00137     }
00138 
00139   if (result != self) memcpy(result, self, len*sizeof(digit_t));
00140 
00141   while (n_digits-- > 0)
00142     {
00143       if (self[n_digits] != 0) break;
00144     }
00145   return n_digits+1;
00146 }
00147 
00169 void ymp_mul_2exp(mp_ref_t result, mp_cref_t self, size_t pow)
00170 {
00171   result->sign = self->sign;
00172   ymp_reserve(result, self->used+pow/DIGIT_BIT+1);
00173   result->used = ymp_lshiftabs(result->digits, self->digits, self->used, pow);
00174 }
00175 
00176 
00189 void ymp_div_2exp(mp_ref_t result, mp_cref_t self, size_t pow)
00190 {
00191   size_t n_shift_digits = pow/DIGIT_BIT;
00192 
00193   if (self->used > n_shift_digits)
00194     {
00195       result->sign = self->sign;
00196       ymp_reserve(result, self->used - n_shift_digits);
00197       result->used
00198         = ymp_rshiftabs(result->digits, self->digits, self->used, pow);
00199     }
00200   else
00201     {
00202       result->used = 0;
00203     }
00204 }
00205 
00206 
00217 void ymp_mod_2exp(mp_ref_t result, mp_cref_t self, size_t pow)
00218 {
00219   size_t n_digits = pow / DIGIT_BIT;
00220   ymp_reserve(result, n_digits>self->used ? self->used : n_digits);
00221   result->sign = self->sign;
00222   result->used = ymp_modabs_2exp(result->digits, self->digits, self->used, pow);
00223 }
00224 
00225 

YMPに対してTue Mar 16 19:23:51 2004に生成されました。 doxygen1.2.14 作者 Dimitri van Heesch, © 1997-2002