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

multiprec.h

解説を見る。
00001 #ifndef MULTIPREC_H
00002 #define MULTIPREC_H
00003 
00004 #include <stdlib.h>
00005 #include <stdio.h>
00006 #include <limits.h>
00007 #include <stdarg.h>
00008 
00009 #ifndef C99
00010 # if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
00011 #  ifndef __CYGWIN__
00012 #   define C99
00013 #  endif
00014 # endif
00015 #endif
00016 
00017 #ifdef C99
00018 # include <stdint.h>
00019 #endif
00020 
00025 typedef unsigned digit_t;
00027 #define DIGIT_BIT (sizeof(digit_t)*CHAR_BIT)
00028 
00029 #define DIGIT_MAX UINT_MAX
00030 #define DIGIT_HIGHEST_BIT ((digit_t)(1<<(DIGIT_BIT-1)))
00031 
00036 typedef unsigned long long double_digit_t;
00038 #define DOUBLE_DIGIT_BIT (sizeof(double_digit_t)*CHAR_BIT)
00039 
00040 #define DOUBLE_DIGIT_MAX ULONGLONG_MAX
00041 
00043 #define HIGH_DIGIT(dd) ((digit_t)((dd) >> DIGIT_BIT))
00044 
00045 #define LOW_DIGIT(dd)  ((digit_t)(dd))
00046 
00047 #define LOW_DIGIT_TO_HIGH_DIGIT(dd) ((dd) << DIGIT_BIT)
00048 
00052 #define MULTIPREC_RADIX (((double_digit_t)DIGIT_MAX)+1)
00053 
00054 
00056 enum mp_sign_t { positive_sign=0, negative_sign=1 };
00057 
00061 struct multiprec
00062 {
00064   enum mp_sign_t sign;
00065 
00067   size_t len;
00068 
00070   size_t used;
00071 
00073   digit_t *digits;
00074 };
00075 
00077 typedef struct multiprec *mp_ref_t;
00078 
00080 typedef const struct multiprec *mp_cref_t;
00081 
00087 #define MULTIPREC_INITIALIZER {positive_sign, 0, 0, NULL}
00088 
00089 
00093 #ifndef MAX
00094 # define MAX(a,b) ( ((a)>(b))?(a):(b) )
00095 #endif
00096 
00097 
00104 #define UINT_IS_2POW(u) ( ((u) & ((u)-1)) == 0 )
00105 
00106 size_t digit_len_to_str_len(size_t len, digit_t r);
00107 
00113 extern void *(*ymp_malloc)(size_t size);
00114 extern void *(*ymp_realloc)(void *pv_mem, size_t size);
00115 extern void (*ymp_free)(void *pv_mem);
00116 
00130 #define YMP_ALLOCATE(result, type, count)                               \
00131 do {                                                                    \
00132   register type *ptr_tmp = (type*)ymp_malloc(sizeof(type)*(count));     \
00133   if (!ptr_tmp)                                                         \
00134     {                                                                   \
00135       ymp_alloc_error("確保失敗", sizeof(type)*(count));                \
00136       break;                                                            \
00137     }                                                                   \
00138   (result) = ptr_tmp;                                                   \
00139 } while(0)
00140 
00141 
00156 #define YMP_REALLOCATE(ptr, type, count)                                    \
00157 do {                                                                        \
00158   register type *ptr_tmp = (type*)ymp_realloc((ptr), sizeof(type)*(count)); \
00159   if (!ptr_tmp)                                                             \
00160    {                                                                        \
00161      ymp_alloc_error("再確保失敗", sizeof(type)*(count));                   \
00162      break;                                                                 \
00163    }                                                                        \
00164   (ptr) = ptr_tmp;                                                          \
00165 } while(0)
00166 
00167 
00174 #define YMP_FREE(ptr) \
00175 ymp_free(ptr)
00176 
00177 
00178 
00192 #define YMP_TEMP_ALLOCATE(result, type, count)                  \
00193 do {                                                            \
00194   register type *ptr_tmp = (type*)alloca(sizeof(type)*(count)); \
00195   if (!ptr_tmp)                                                 \
00196     {                                                           \
00197       ymp_alloc_error("確保失敗", sizeof(type)*(count));        \
00198       break;                                                    \
00199     }                                                           \
00200   (result) = ptr_tmp;                                           \
00201 } while(0)
00202 
00203 
00204 
00213 #define YMP_ALLOC_DIGITS(self, new_len)                 \
00214 do {                                                    \
00215   YMP_ALLOCATE((self)->digits, digit_t, new_len);       \
00216   (self)->len = new_len;                                \
00217 } while(0)
00218 
00227 #define YMP_REALLOC_DIGITS(self, new_len)               \
00228 do {                                                    \
00229   YMP_REALLOCATE((self)->digits, digit_t, new_len);     \
00230   (self)->len = new_len;                                \
00231 } while(0)
00232 
00239 #define YMP_FREE_DIGITS(self)                   \
00240 do {                                            \
00241   YMP_FREE((self)->digits);                     \
00242   (self)->digits = NULL;                        \
00243 } while(0)
00244 
00245 
00250 extern void (*ymp_warning)(const char *format, ...);
00251 extern void (*ymp_error)(const char *format, ...);
00252 extern void (*ymp_fatal)(const char *format, ...);
00253 extern void (*ymp_alloc_error)(const char *psz_msg, size_t size);
00261 void ymp_initialize(mp_ref_t self); 
00262 void ymp_destroy(mp_ref_t self);
00263 void ymp_reinitialize(mp_ref_t self);
00264 
00265 void ymp_initialize_by_mp(mp_ref_t self, mp_cref_t other);
00266 void ymp_reserve_and_initialize_by_digit(mp_ref_t self, size_t len, digit_t d);
00267 void ymp_reserve_and_initialize(mp_ref_t self, size_t len);
00268 
00276 #define ymp_alloca_initialize(self, new_len)                    \
00277 do {                                                            \
00278   (self)->sign = positive_sign;                                 \
00279   (self)->len = (self)->used = 0;                               \
00280   YMP_TEMP_ALLOCATE((self)->digits, digit_t, (new_len));        \
00281   (self)->len = (new_len);                                      \
00282 } while (0)
00283 
00284 
00285 void ymp_initialize_by_array(mp_ref_t self, size_t len, const digit_t *array);
00286 void ymp_initialize_by_digit(mp_ref_t self, digit_t d);
00287 void ymp_initialize_by_string(mp_ref_t self, 
00288                               const char *text, char **endptr, unsigned radix);
00289 
00290 void ymp_initialize_by_char(mp_ref_t self, signed char val);
00291 void ymp_initialize_by_short(mp_ref_t self, short val);
00292 void ymp_initialize_by_int(mp_ref_t self, int val);
00293 void ymp_initialize_by_long(mp_ref_t self, long val);
00294 void ymp_initialize_by_uchar(mp_ref_t self, unsigned char val);
00295 void ymp_initialize_by_ushort(mp_ref_t self, unsigned short val);
00296 void ymp_initialize_by_uint(mp_ref_t self, unsigned val);
00297 void ymp_initialize_by_ulong(mp_ref_t self, unsigned long val);
00298 #ifdef C99
00299 void ymp_initialize_by_intmax(mp_ref_t self, intmax_t val);
00300 void ymp_initialize_by_uintmax(mp_ref_t self, uintmax_t val);
00301 #endif
00302 void ymp_initialize_by_double(mp_ref_t self, double val);
00303 
00304 mp_ref_t ymp_dup(mp_cref_t orig);
00305 
00306 void ymp_reserve(mp_ref_t self, size_t len);
00307 void ymp_cut_down(mp_ref_t self);
00308 
00318 void ymp_assign_abs(mp_ref_t self, mp_cref_t other);
00319 void ymp_assign_abs_digit(mp_ref_t self, digit_t other);
00320 void ymp_assign_abs_array(mp_ref_t self, size_t len, const digit_t *array);
00323 void ymp_assign(mp_ref_t self, mp_cref_t other);
00324 void ymp_assign_digit(mp_ref_t self, digit_t other);
00325 void ymp_assign_array(mp_ref_t self, size_t len, const digit_t *array);
00326 void ymp_assign_string(mp_ref_t self, 
00327                        const char *text, char **endptr, unsigned radix);
00328 
00329 void ymp_assign_char(mp_ref_t self, signed char val);
00330 void ymp_assign_short(mp_ref_t self, short val);
00331 void ymp_assign_int(mp_ref_t self, int val);
00332 void ymp_assign_long(mp_ref_t self, long val);
00333 void ymp_assign_uchar(mp_ref_t self, unsigned char val);
00334 void ymp_assign_ushort(mp_ref_t self, unsigned short val);
00335 void ymp_assign_uint(mp_ref_t self, unsigned val);
00336 void ymp_assign_ulong(mp_ref_t self, unsigned long val);
00337 #ifdef C99
00338 void ymp_assign_intmax(mp_ref_t self, intmax_t val);
00339 void ymp_assign_uintmax(mp_ref_t self, uintmax_t val);
00340 #endif
00341 void ymp_assign_double(mp_ref_t self, double val);
00342 void ymp_assign_2exp(mp_ref_t self, size_t pow);
00343 
00344 
00351 #define ymp_assign_zero(self)                   \
00352 (void)((self)->used = 0)
00353 
00354 
00355 void ymp_swap(mp_ref_t self, mp_ref_t other);
00368 size_t
00369 ymp_rshiftabs(digit_t *result, const digit_t *source, size_t len, size_t width);
00370 size_t
00371 ymp_lshiftabs(digit_t *result, const digit_t *source, size_t len, size_t width);
00383 size_t ymp_addabs(digit_t *result, const digit_t *lhs, const digit_t *rhs,
00384                   size_t lhs_len, size_t rhs_len);
00385 size_t ymp_subabs(digit_t *result, const digit_t *lhs, const digit_t *rhs,
00386                   size_t lhs_len, size_t rhs_len);
00387 size_t ymp_mulabs(digit_t *result, const digit_t *lhs, const digit_t *rhs,
00388                   size_t lhs_len, size_t rhs_len);
00389 size_t ymp_mulabs_digit(digit_t *result, const digit_t *lhs, digit_t rhs,
00390                         size_t lhs_len);
00391 size_t ymp_modmulabs(digit_t *result, const digit_t *lhs, const digit_t *rhs, 
00392                      const digit_t *modulus,
00393                      size_t lhs_len, size_t rhs_len, size_t modulus_len);
00394 size_t ymp_modmulabs_2exp(digit_t *result,
00395                           const digit_t *lhs, const digit_t *rhs, 
00396                           size_t pow, size_t lhs_len, size_t rhs_len);
00397 
00398 size_t ymp_modabs_2exp(digit_t *result, const digit_t *self, 
00399                        size_t len, size_t pow);
00400 
00401 size_t ymp_divmodabs(digit_t *quotient, digit_t *remainder,
00402                      const digit_t *lhs, const digit_t *rhs,
00403                      size_t lhs_len, size_t rhs_len);
00404 digit_t ymp_divmodabs_digit(digit_t *quotient, const digit_t *lhs, digit_t rhs,
00405                             size_t lhs_len);
00406 
00407 
00408 
00409 
00410 size_t ymp_modpowabs(digit_t *result, 
00411                      const digit_t *source, const digit_t *modulus, 
00412                      const digit_t *pow,
00413                      size_t source_len, size_t modulus_len, size_t pow_len);
00414 
00415 size_t ymp_modpowabs_z(digit_t *result, 
00416                        const digit_t *source, const digit_t *modulus,
00417                        size_t source_len, size_t modulus_len, size_t pow);
00418 
00419 size_t ymp_modpowabs_2exp_z(digit_t *result, const digit_t *source,
00420                             size_t len, size_t emod, size_t pow);
00421 
00422 size_t ymp_powabs(digit_t *result, const digit_t *source, 
00423                   size_t source_len, size_t pow);
00426 void ymp_neg(mp_ref_t result, mp_cref_t orig);
00427 void ymp_add(mp_ref_t result, mp_cref_t self, mp_cref_t other);
00428 void ymp_sub(mp_ref_t result, mp_cref_t self, mp_cref_t other);
00429 void ymp_add_digit(mp_ref_t result, mp_cref_t self, digit_t other);
00430 void ymp_sub_digit(mp_ref_t result, mp_cref_t self, digit_t other);
00431 
00432 void ymp_mul(mp_ref_t result, mp_cref_t self, mp_cref_t other);
00433 void ymp_mul_digit(mp_ref_t result, mp_cref_t self, digit_t other);
00434 void ymp_modmul(mp_ref_t result, 
00435                 mp_cref_t self, mp_cref_t other, mp_cref_t modulus);
00436 void ymp_modmul_2exp(mp_ref_t result,
00437                      mp_cref_t self, mp_cref_t other, size_t pow);
00438 
00439 void ymp_mul_2exp(mp_ref_t result, mp_cref_t self, size_t pow);
00440 void ymp_div_2exp(mp_ref_t result, mp_cref_t self, size_t pow);
00441 void ymp_mod_2exp(mp_ref_t result, mp_cref_t self, size_t pow);
00442 
00443 
00444 void ymp_divmod(mp_ref_t quotient, mp_ref_t remainder, mp_cref_t self, mp_cref_t other);
00445 digit_t ymp_divmod_digit(mp_ref_t quotient, mp_cref_t self, digit_t other);
00446 
00458 #define ymp_div(quotient, self, other)          \
00459 ymp_divmod((quotient), NULL, (self), (other))
00460 
00470 #define ymp_mod(remainder, self, other)         \
00471 ymp_divmod(NULL, (remainder), (self), (other))
00472 
00482 #define ymp_div_digit(quotient, self, other)    \
00483 (void)ymp_divmod_digit((quotient), (self), (other))
00484 
00494 #define ymp_mod_digit(self, other)              \
00495 ymp_divmod_digit(NULL, (self), (other))
00496 
00497 
00498 
00499 int ymp_div_if_divisible(mp_ref_t quotient, mp_cref_t self, mp_cref_t other);
00500 int ymp_div_if_divisible_digit(mp_ref_t quotient, 
00501                                mp_cref_t self, digit_t other);
00502 
00512 #define ymp_is_divisible(self, other)           \
00513 ymp_div_if_divisible(NULL, (self), (other))
00514 
00524 #define ymp_is_divisible_digit(self, other)             \
00525 ymp_div_if_divisible_digit(NULL, (self), (other))
00526 
00527 void ymp_pow(mp_ref_t result, mp_cref_t self, size_t pow);
00528 void ymp_modpow(mp_ref_t result, mp_cref_t self, 
00529                 mp_cref_t modulus, mp_cref_t pow);
00530 void ymp_modpow_z(mp_ref_t result, mp_cref_t self, mp_cref_t modulus, size_t pow);
00531 
00532 void ymp_modpow_2exp_z(mp_ref_t result, mp_cref_t self, size_t emod, size_t pow);
00533 void ymp_iroot(mp_ref_t result, mp_cref_t self, size_t pow);
00534 
00540 void ymp_euclid(mp_ref_t g, mp_cref_t a, mp_cref_t b);
00541 void ymp_euclid_ex(mp_ref_t g, mp_ref_t s, mp_ref_t t,
00542                    mp_cref_t a, mp_cref_t b);
00543 void ymp_multi_euclid(mp_ref_t result, 
00544                       size_t len, const struct multiprec *ary);
00545 int ymp_modinv(mp_ref_t result, mp_cref_t self, mp_cref_t modulus);
00546 int ymp_binary_sunzi(mp_ref_t result, 
00547                      const mp_cref_t remainders[2], const mp_cref_t moduli[2]);
00548 
00549 int ymp_proot(mp_ref_t result, mp_cref_t self, size_t pow);
00550 int ymp_is_perfect_power(mp_cref_t self);
00551 
00559 void ymp_dump(FILE *fp, mp_cref_t mz);
00560 int ymp_print_hex(FILE *fp, mp_cref_t mz);
00561 
00566 int ymp_snprint(char *buf, size_t len, mp_cref_t mz, digit_t radix);
00567 int ymp_fprint(FILE *fp, mp_cref_t mz, digit_t radix);
00568 
00579 int ymp_compare_abs(mp_cref_t lhs, mp_cref_t rhs);
00580 int ymp_compare(mp_cref_t lhs, mp_cref_t rhs);
00581 int ymp_compare_digit(mp_cref_t lhs, digit_t rhs);
00582 int ymp_is_zero(mp_cref_t self);
00583 int ymp_is_even(mp_cref_t self);
00584 
00590 #define ymp_is_odd(self) !ymp_is_even((self))
00591 
00599 size_t ymp_ilog2(mp_cref_t self);
00600 size_t ymp_abs_clog2(const digit_t *digits, size_t len);
00601 
00606 #endif

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