関数 | |
| size_t | ymp_addabs (digit_t *result, const digit_t *lhs, const digit_t *rhs, size_t lhs_len, size_t rhs_len) |
| digit_tの列で表されている絶対値の和を求める. より詳しく... | |
| size_t | ymp_subabs (digit_t *result, const digit_t *lhs, const digit_t *rhs, size_t lhs_len, size_t rhs_len) |
| digit_tの列で表されている絶対値の差を求める. より詳しく... | |
| digit_t | ymp_divmodabs_digit (digit_t *quotient, const digit_t *lhs, const digit_t rhs, size_t lhs_len) |
| 多倍長の自然数をdigit_tで割る. より詳しく... | |
| void | do_divmodabs (digit_t *quotient, digit_t *lhs, const digit_t *rhs, size_t lhs_len, size_t rhs_len) |
| 多倍長自然数の除算の実行. より詳しく... | |
| size_t | ymp_divmodabs (digit_t *quotient, digit_t *remainder, const digit_t *lhs, const digit_t *rhs, size_t lhs_len, size_t rhs_len) |
| 多倍長自然数の除算. より詳しく... | |
| size_t | ymp_mulabs (digit_t *result, const digit_t *lhs, const digit_t *rhs, size_t lhs_len, size_t rhs_len) |
| digit_tの列で表されている絶対値の積を求める. より詳しく... | |
| size_t | ymp_mulabs_digit (digit_t *result, const digit_t *lhs, digit_t rhs, size_t lhs_len) |
| digit_tの列で表されている絶対値にdigit_tを掛ける. より詳しく... | |
| size_t | ymp_modmulabs (digit_t *result, const digit_t *lhs, const digit_t *rhs, const digit_t *modulus, size_t lhs_len, size_t rhs_len, size_t modulus_len) |
| 多倍長自然数の積の剰余を求める. より詳しく... | |
| size_t | ymp_modmulabs_2exp (digit_t *result, const digit_t *lhs, const digit_t *rhs, size_t pow, size_t lhs_len, size_t rhs_len) |
| 多倍長自然数の積の、2の冪による剰余を求める. より詳しく... | |
| size_t | ymp_modpowabs_z (digit_t *result, const digit_t *source, const digit_t *modulus, size_t source_len, size_t modulus_len, size_t pow) |
| 多倍長自然数の冪の剰余を求める(冪指数はsize_t). より詳しく... | |
| size_t | ymp_modpowabs_2exp_z (digit_t *result, const digit_t *source, size_t len, size_t emod, size_t pow) |
| 多倍長の自然数の冪の、2の冪による剰余を求める(冪指数はsize_t). より詳しく... | |
| size_t | ymp_modpowabs (digit_t *result, const digit_t *source, const digit_t *modulus, const digit_t *pow, size_t source_len, size_t modulus_len, size_t pow_len) |
| 多倍長自然数の冪の剰余を求める(冪指数は多倍長). より詳しく... | |
| size_t | ymp_powabs (digit_t *result, const digit_t *source, size_t source_len, size_t pow) |
| 多倍長自然数の冪 (冪指数はsize_t). より詳しく... | |
| size_t | ymp_modabs_2exp (digit_t *result, const digit_t *self, size_t len, size_t pow) |
| 多倍長自然数の2の冪乗による剰余. より詳しく... | |
|
||||||||||||||||||||||||
|
digit_tの列で表されている絶対値の和を求める.
参照 digit_t, double_digit_t, HIGH_DIGIT, と LOW_DIGIT.
00039 {
00040 double_digit_t tmp = 0;
00041 size_t i;
00042
00043 for ( i = 0; i < rhs_len; ++i)
00044 {
00045 tmp += lhs[i];
00046 tmp += rhs[i];
00047 result[i] = LOW_DIGIT(tmp);
00048 tmp = HIGH_DIGIT(tmp);
00049 }
00050 for ( ; i < lhs_len; ++i)
00051 {
00052 tmp += lhs[i];
00053 result[i] = LOW_DIGIT(tmp);
00054 tmp = HIGH_DIGIT(tmp);
00055 }
00056 if (LOW_DIGIT(tmp))
00057 {
00058 result[i++] = LOW_DIGIT(tmp);
00059 }
00060 return i;
00061 }
|
|
||||||||||||||||||||||||
|
digit_tの列で表されている絶対値の差を求める.
参照 digit_t, double_digit_t, HIGH_DIGIT, LOW_DIGIT, と MULTIPREC_RADIX.
00083 {
00084 double_digit_t tmp = 1;
00085 size_t i;
00086
00087 for ( i = 0; i < rhs_len; ++i)
00088 {
00089 tmp += MULTIPREC_RADIX - 1;
00090 tmp += lhs[i];
00091 tmp -= rhs[i];
00092 result[i] = LOW_DIGIT(tmp);
00093 tmp = HIGH_DIGIT(tmp);
00094 }
00095 for ( ; i < lhs_len; ++i)
00096 {
00097 tmp += MULTIPREC_RADIX - 1;
00098 tmp += lhs[i];
00099 result[i] = LOW_DIGIT(tmp);
00100 tmp = HIGH_DIGIT(tmp);
00101 }
00102 while (i-- > 0)
00103 {
00104 if (result[i]) break;
00105 }
00106 return ++i;
00107 }
|
|
||||||||||||||||||||
|
多倍長の自然数をdigit_tで割る.
参照 digit_t, double_digit_t, LOW_DIGIT, と LOW_DIGIT_TO_HIGH_DIGIT.
00034 {
00035 double_digit_t tmp = 0;
00036 register size_t i = lhs_len;
00037
00038 while (i-- > 0)
00039 {
00040 tmp = LOW_DIGIT_TO_HIGH_DIGIT(tmp);
00041 tmp += lhs[i];
00042 if (quotient) quotient[i] = tmp/rhs;
00043 tmp %= rhs;
00044 }
00045 return LOW_DIGIT(tmp);
00046 }
|
|
||||||||||||||||||||||||
|
多倍長自然数の除算の実行.
参照 DIGIT_HIGHEST_BIT, digit_t, double_digit_t, HIGH_DIGIT, LOW_DIGIT, LOW_DIGIT_TO_HIGH_DIGIT, と MULTIPREC_RADIX. 呼出 ymp_divmodabs.
00075 {
00076 double_digit_t lhs_top;
00077 size_t i;
00078
00079 i = lhs_len; lhs_top = lhs[--i];
00080 while (i-- >= rhs_len)
00081 {
00082 size_t j;
00083 digit_t q;
00084 double_digit_t tmp;
00085
00086 /* 最上位桁による仮商を定める */
00087 lhs_top = LOW_DIGIT_TO_HIGH_DIGIT(lhs_top);
00088 lhs_top += lhs[i];
00089 q = lhs_top / rhs[rhs_len-1];
00090
00091 /* (被除数)*(仮商) を被除数から引いてみる*/
00092 tmp = 0;
00093 for (j=0; j<rhs_len; ++j)
00094 {
00095 double_digit_t tmp2 = MULTIPREC_RADIX;
00096 tmp += ((double_digit_t)rhs[j]) * q;
00097
00098 tmp2 += lhs[i-rhs_len+j+1];
00099 tmp2 -= LOW_DIGIT(tmp);
00100 lhs[i-rhs_len+j+1] = LOW_DIGIT(tmp2);
00101
00102 tmp = HIGH_DIGIT(tmp);
00103 tmp += !HIGH_DIGIT(tmp2);
00104 }
00105 tmp = MULTIPREC_RADIX - tmp;
00106 tmp += lhs[i+1];
00107 lhs[i+1] = LOW_DIGIT(tmp);
00108
00109 /* 引き過ぎていたら、最上位桁の最上位bitは1の筈 */
00110 while (lhs[i+1] & DIGIT_HIGHEST_BIT)
00111 {
00112 /* 商を減らし */
00113 --q;
00114
00115 /* その分だけ足し戻す */
00116 tmp = 0;
00117 for (j=0; j<rhs_len; ++j)
00118 {
00119 tmp += lhs[i-rhs_len+j+1];
00120 tmp += rhs[j];
00121 lhs[i-rhs_len+j+1] = LOW_DIGIT(tmp);
00122 tmp = HIGH_DIGIT(tmp);
00123 }
00124 lhs[i+1] += LOW_DIGIT(tmp);
00125 }
00126
00127 /* 得られた商を書き込む */
00128 if (quotient) quotient[i+1-rhs_len] = q;
00129
00130 lhs_top = lhs[i];
00131 }
00132 }
|
|
||||||||||||||||||||||||||||
|
多倍長自然数の除算.
参照 DIGIT_HIGHEST_BIT, digit_t, do_divmodabs, double_digit_t, HIGH_DIGIT, LOW_DIGIT, LOW_DIGIT_TO_HIGH_DIGIT, ymp_fatal, と YMP_TEMP_ALLOCATE.
00162 {
00163 int shift_width; /* シフト幅 */
00164 digit_t hd; /* rhsの最上位桁 */
00165 size_t i;
00166 digit_t *new_lhs, *new_rhs; /* 被除数、除数を各々シフトしたもの */
00167 double_digit_t tmp;
00168
00169 /* 0除算を弾く */
00170 if (rhs_len==0 || (rhs_len==1 && rhs[0]==0))
00171 {
00172 ymp_fatal("0による除算");
00173 return 0;
00174 }
00175
00176 /* シフトした被除数、除数を格納するための領域を確保 */
00177 YMP_TEMP_ALLOCATE(new_lhs, digit_t, lhs_len+1);
00178 YMP_TEMP_ALLOCATE(new_rhs, digit_t, rhs_len);
00179
00180 /* 適切なシフト幅を算出 */
00181 shift_width = 0;
00182 hd = rhs[rhs_len-1];
00183 while ( !(hd & DIGIT_HIGHEST_BIT) )
00184 {
00185 ++shift_width;
00186 hd <<= 1;
00187 }
00188
00189 /* 除数をshift_widthだけシフト */
00190 i = rhs_len; tmp = rhs[--i];
00191 while (i-- > 0)
00192 {
00193 tmp = LOW_DIGIT_TO_HIGH_DIGIT(tmp);
00194 tmp += rhs[i];
00195 tmp <<= shift_width;
00196 new_rhs[i+1] = HIGH_DIGIT(tmp);
00197 tmp = rhs[i];
00198 }
00199 new_rhs[0] = rhs[0] << shift_width;
00200
00201 /* 被除数をshift_widthだけシフト */
00202 tmp = 0; i=lhs_len;
00203 while(i-- > 0)
00204 {
00205 tmp += lhs[i];
00206 tmp <<= shift_width;
00207 new_lhs[i+1] = HIGH_DIGIT(tmp);
00208
00209 tmp = lhs[i];
00210 tmp = LOW_DIGIT_TO_HIGH_DIGIT(tmp);
00211 }
00212 new_lhs[0] = lhs[0] << shift_width;
00213
00214 /* シフトした状態で、除算を実行 */
00215 do_divmodabs(quotient, new_lhs, new_rhs, lhs_len+1, rhs_len);
00216
00217 /* 今、シフトされた剰余がnew_lhsに入っている */
00218
00219 if (remainder)
00220 {
00221 /* 剰余を逆シフトして復元しながら、非0の最高桁数を探す */
00222 size_t rem_used = 0;
00223 tmp = 0; i=rhs_len;
00224 while (i-- > 0)
00225 {
00226 tmp += new_lhs[i];
00227 remainder[i] = LOW_DIGIT(tmp >> shift_width);
00228
00229 if (remainder[i] && !rem_used) rem_used = i+1;
00230
00231 tmp = new_lhs[i];
00232 tmp = LOW_DIGIT_TO_HIGH_DIGIT(tmp);
00233 }
00234 return rem_used;
00235 }
00236 else
00237 {
00238 return 0;
00239 }
00240 }
|
|
||||||||||||||||||||||||
|
digit_tの列で表されている絶対値の積を求める.
参照 digit_t, double_digit_t, HIGH_DIGIT, と LOW_DIGIT.
00033 {
00034 double_digit_t tmp=0;
00035 size_t i=0, j=0;
00036
00037 if (lhs_len == 0 || rhs_len == 0) return 0;
00038 if ((lhs_len==1 && lhs[0]==0) || (rhs_len==1 && rhs[0]==0)) return 0;
00039
00040 memset(result, 0, (lhs_len+rhs_len)*sizeof(digit_t));
00041 for (i=0; i<lhs_len; ++i)
00042 {
00043 tmp = 0;
00044 for (j=0; j<rhs_len; ++j)
00045 {
00046 tmp += ((double_digit_t)lhs[i]) * rhs[j];
00047 tmp += result[i+j];
00048
00049 result[i+j] = LOW_DIGIT(tmp);
00050 tmp = HIGH_DIGIT(tmp);
00051 }
00052 result[i+j] = LOW_DIGIT(tmp);
00053 }
00054 if (tmp) ++i;
00055 return i+j-1;
00056 }
|
|
||||||||||||||||||||
|
digit_tの列で表されている絶対値にdigit_tを掛ける.
参照 digit_t, double_digit_t, HIGH_DIGIT, と LOW_DIGIT.
00078 {
00079 double_digit_t tmp = 0, tmp2, tmp3;
00080 size_t i;
00081 for (i=0; i<lhs_len; ++i)
00082 {
00083 tmp2 = ((double_digit_t)lhs[i]) * rhs;
00084 tmp3 = LOW_DIGIT(tmp);
00085 tmp3 += LOW_DIGIT(tmp2);
00086
00087 result[i] = LOW_DIGIT(tmp3);
00088
00089 tmp = HIGH_DIGIT(tmp);
00090 tmp += HIGH_DIGIT(tmp2);
00091 tmp += HIGH_DIGIT(tmp3);
00092 }
00093 if (LOW_DIGIT(tmp))
00094 {
00095 result[i] = LOW_DIGIT(tmp);
00096 ++i;
00097 }
00098 return i;
00099 }
|
|
||||||||||||||||||||||||||||||||
|
多倍長自然数の積の剰余を求める. (result) := (lhs) * (rhs) % (modulus) ( ただし、(lhs), (rhs), (modulus)は自然数 )
参照 digit_t, ymp_divmodabs, ymp_mulabs, と YMP_TEMP_ALLOCATE.
00123 {
00124 digit_t *product_digits;
00125 size_t product_used;
00126
00127 YMP_TEMP_ALLOCATE(product_digits, digit_t, lhs_len+rhs_len);
00128
00129 product_used = ymp_mulabs(product_digits, lhs, rhs, lhs_len, rhs_len);
00130
00131 if (product_used < modulus_len)
00132 {
00133 memcpy(result, product_digits, sizeof(digit_t)*product_used);
00134 return product_used;
00135 }
00136 else
00137 {
00138 return ymp_divmodabs(NULL, result, product_digits, modulus,
00139 product_used, modulus_len);
00140 }
00141 }
|
|
||||||||||||||||||||||||||||
|
多倍長自然数の積の、2の冪による剰余を求める. (result) := (lhs) * (rhs) % (2**pow) ( ただし、(lhs), (rhs)は自然数 )
参照 DIGIT_BIT, digit_t, double_digit_t, HIGH_DIGIT, LOW_DIGIT, と YMP_TEMP_ALLOCATE.
00166 {
00167 size_t n_digits, n_bits;
00168
00169 size_t max_len;
00170 digit_t *product;
00171
00172 double_digit_t tmp;
00173 size_t i, j;
00174
00175 if (lhs_len == 0 || rhs_len == 0) return 0;
00176 if ((lhs_len==1 && lhs[0]==0) || (rhs_len==1 && rhs[0]==0)) return 0;
00177
00178
00179 n_digits = pow / DIGIT_BIT; n_bits = pow % DIGIT_BIT;
00180 max_len = n_digits + (n_bits != 0);
00181
00182 if (result == lhs || result == rhs)
00183 {
00184 YMP_TEMP_ALLOCATE(product, digit_t, max_len);
00185 }
00186 else
00187 {
00188 product = result;
00189 }
00190
00191 memset(product, 0, max_len*sizeof(digit_t));
00192
00193 if (lhs_len > max_len) lhs_len = max_len;
00194 for (i=0; i<lhs_len; ++i)
00195 {
00196 size_t bound = max_len - i;
00197 tmp = 0;
00198 for (j=0; j<rhs_len && j<bound ; ++j)
00199 {
00200 tmp += ((double_digit_t)lhs[i]) * rhs[j];
00201 tmp += product[i+j];
00202
00203 product[i+j] = LOW_DIGIT(tmp);
00204 tmp = HIGH_DIGIT(tmp);
00205 }
00206 if (i+j < max_len) product[i+j] = LOW_DIGIT(tmp);
00207 }
00208
00209 if (n_bits) product[n_digits] &= (1u << n_bits)-1;
00210
00211 while (max_len-- > 0)
00212 {
00213 if (product[max_len]) break;
00214 }
00215 ++max_len;
00216
00217 if (product != result) memcpy(result, product, max_len * sizeof(digit_t));
00218
00219 return max_len;
00220 }
|
|
||||||||||||||||||||||||||||
|
多倍長自然数の冪の剰余を求める(冪指数はsize_t). <result> := <base>**<pow> % <modulus>
参照 digit_t, ymp_divmodabs, ymp_modmulabs, と YMP_TEMP_ALLOCATE.
00370 {
00371 /* 繰りかえし2乗法による */
00372
00373 digit_t *powered_digits; /* self**(2の冪)を保持 */
00374 size_t powered_used; /* powered_digitsの先に格納された有効要素数 */
00375 size_t result_used;
00376
00377 /* result == modulus の場合、複製 */
00378 if (result == modulus)
00379 {
00380 digit_t *new_modulus;
00381 YMP_TEMP_ALLOCATE(new_modulus, digit_t, modulus_len);
00382 memcpy(new_modulus, modulus, sizeof(digit_t)*modulus_len);
00383 modulus = new_modulus;
00384 }
00385
00386 /* <powered> = <self> ** (2**0) */
00387 YMP_TEMP_ALLOCATE(powered_digits, digit_t, modulus_len*2);
00388 if (source_len < modulus_len)
00389 {
00390 powered_used = source_len;
00391 memcpy(powered_digits, source, source_len*sizeof(digit_t));
00392 }
00393 else
00394 {
00395 powered_used = ymp_divmodabs(NULL, powered_digits,
00396 source, modulus, source_len, modulus_len);
00397
00398 }
00399
00400 /* <result> = 1 */
00401 result_used = 1; result[0] = 1;
00402
00403 for (;;)
00404 {
00405 if (pow & 0x01)
00406 {
00407 result_used = ymp_modmulabs(result,
00408 result, powered_digits, modulus,
00409 result_used, powered_used, modulus_len);
00410 }
00411
00412 pow >>= 1;
00413 if (!pow) return result_used;
00414
00415 powered_used = ymp_modmulabs(powered_digits,
00416 powered_digits, powered_digits, modulus,
00417 powered_used, powered_used, modulus_len);
00418 }
00419 }
|
|
||||||||||||||||||||||||
|
多倍長の自然数の冪の、2の冪による剰余を求める(冪指数はsize_t). (result) := (source)**(pow) % (2**emod)
参照 DIGIT_BIT, digit_t, ymp_modabs_2exp, ymp_modmulabs_2exp, と YMP_TEMP_ALLOCATE.
00438 {
00439 /* 繰りかえし2乗法による */
00440
00441 digit_t *powered_digits; /* self**(2の冪)を保持 */
00442 size_t powered_used; /* powered_digitsの先に格納された有効要素数 */
00443 size_t result_used; /* resultに格納されている要素数 */
00444 size_t mod_len = emod / DIGIT_BIT + 1;
00445
00446 /* <powered> = <self> ** (2**0) */
00447 YMP_TEMP_ALLOCATE(powered_digits, digit_t, mod_len);
00448 powered_used = ymp_modabs_2exp(powered_digits, source, len, emod);
00449
00450 /* <result> = 1 */
00451 result_used = 1; result[0] = 1;
00452
00453 for (;;)
00454 {
00455 if (pow & 0x01)
00456 {
00457 result_used = ymp_modmulabs_2exp(result, result, powered_digits,
00458 emod, result_used, powered_used);
00459 }
00460
00461 pow >>= 1;
00462 if (!pow) return result_used;
00463
00464 powered_used = ymp_modmulabs_2exp(powered_digits,
00465 powered_digits, powered_digits,
00466 emod, powered_used, powered_used);
00467 }
00468 }
|
|
||||||||||||||||||||||||||||||||
|
多倍長自然数の冪の剰余を求める(冪指数は多倍長). <result> := <self>**<pow> % <modulus>
参照 DIGIT_HIGHEST_BIT, digit_t, ymp_divmodabs, ymp_modmulabs, と YMP_TEMP_ALLOCATE.
00495 {
00496 /* 繰りかえし2乗法による */
00497
00498 size_t i; /* pow->digits[]内のindex */
00499 digit_t bit_mask; /* pow->digits[i]内のbitテスト用 */
00500
00501 digit_t *powered_digits; /* self**(2の冪)を保持 */
00502 size_t powered_used; /* powered_digitsの先に格納された有効要素数 */
00503
00504 size_t result_used; /* resultの先に格納された有効要素数 */
00505
00506 /* result == modulus の場合、複製 */
00507 if (result == modulus)
00508 {
00509 digit_t *new_modulus;
00510 YMP_TEMP_ALLOCATE(new_modulus, digit_t, modulus_len);
00511 memcpy(new_modulus, modulus, sizeof(digit_t)*modulus_len);
00512 modulus = new_modulus;
00513 }
00514
00515 /* result == pow の場合、複製 */
00516 if (result == pow)
00517 {
00518 digit_t *new_pow;
00519 YMP_TEMP_ALLOCATE(new_pow, digit_t, pow_len);
00520 memcpy(new_pow, pow, sizeof(digit_t)*pow_len);
00521 pow = new_pow;
00522 }
00523
00524 /* <powered> = <self> ** (2**0) */
00525 YMP_TEMP_ALLOCATE(powered_digits, digit_t, modulus_len*2);
00526 if (source_len < modulus_len)
00527 {
00528 powered_used = source_len;
00529 memcpy(powered_digits, source, sizeof(digit_t)*source_len);
00530 }
00531 else
00532 {
00533 powered_used = ymp_divmodabs(NULL, powered_digits,
00534 source, modulus, source_len, modulus_len);
00535
00536 }
00537
00538 /* <result> = 1 */
00539 result_used = 1; result[0] = 1;
00540
00541 i=0; bit_mask=1;
00542 for (;;)
00543 {
00544 if (pow[i] & bit_mask)
00545 {
00546 result_used = ymp_modmulabs(result,
00547 result, powered_digits, modulus,
00548 result_used, powered_used, modulus_len);
00549 }
00550
00551 if (bit_mask == DIGIT_HIGHEST_BIT)
00552 {
00553 bit_mask = 1;
00554 ++i;
00555 if (i==pow_len) return result_used;
00556 }
00557 else
00558 {
00559 bit_mask <<= 1;
00560 if (i==pow_len-1 && pow[i] < bit_mask) return result_used;
00561 }
00562
00563 powered_used = ymp_modmulabs(powered_digits,
00564 powered_digits, powered_digits, modulus,
00565 powered_used, powered_used, modulus_len);
00566 }
00567 }
|
|
||||||||||||||||||||
|
多倍長自然数の冪 (冪指数はsize_t). <result> := <self>**<pow>
参照 digit_t, ymp_mulabs, と YMP_TEMP_ALLOCATE.
00587 {
00588 /* 繰りかえし2乗法による */
00589 digit_t *tmp_digits; /* 一時的にdigit_t列を待避する為の領域をポイント */
00590 digit_t *powered_digits; /* self**(2の冪)を保持 */
00591 size_t powered_used; /* powered_digitsの先に格納された有効要素数 */
00592 size_t result_used;
00593
00594 if (pow == 0)
00595 {
00596 result[0] = 1;
00597 return 1;
00598 }
00599 /* 以下、<result> >= <source>を仮定できる */
00600
00601
00602 /* 一時領域を確保 */
00603 YMP_TEMP_ALLOCATE(tmp_digits, digit_t, source_len*pow);
00604
00605 /* <powered> = <self> ** (2**0) */
00606 YMP_TEMP_ALLOCATE(powered_digits, digit_t, source_len*pow);
00607 powered_used = source_len;
00608 memcpy(powered_digits, source, sizeof(digit_t)*source_len);
00609
00610 /* <result> = 1 */
00611 result_used = 1; result[0] = 1;
00612
00613
00614
00615 /* 繰りかえし2乗法 */
00616 for (;;)
00617 {
00618 if (pow & 0x01)
00619 {
00620 memcpy(tmp_digits, result, sizeof(digit_t)*result_used);
00621 result_used = ymp_mulabs(result, tmp_digits, powered_digits,
00622 result_used, powered_used);
00623 }
00624
00625 pow >>= 1;
00626 if (!pow) return result_used;
00627
00628 memcpy(tmp_digits, powered_digits, sizeof(digit_t)*powered_used);
00629 powered_used = ymp_mulabs(powered_digits, tmp_digits, tmp_digits,
00630 powered_used, powered_used);
00631 }
00632 }
|
|
||||||||||||||||||||
|
多倍長自然数の2の冪乗による剰余. <self>を2のpow乗で割った剰余をresultに格納する。
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 }
|
1.2.14 作者 Dimitri van Heesch,
© 1997-2002