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

construct.c

解説を見る。
00001 #include "multiprec.h"
00002 #include <string.h>
00003 #include <math.h>
00004 
00019 inline void
00020 ymp_initialize(mp_ref_t self)
00021 {
00022   static const struct multiprec prototype = MULTIPREC_INITIALIZER;
00023   memcpy(self, &prototype, sizeof(struct multiprec));
00024 }
00025 
00026 
00032 inline void
00033 ymp_destroy(mp_ref_t self)
00034 {
00035   YMP_FREE_DIGITS(self);
00036 }
00037 
00045 void
00046 ymp_reinitialize(mp_ref_t self)
00047 {
00048   ymp_destroy(self);
00049   ymp_initialize(self);
00050 }
00051 
00052 
00060 inline void
00061 ymp_initialize_by_mp(mp_ref_t self, mp_cref_t other)
00062 {
00063   memcpy(self, other, sizeof(*self)-sizeof(digit_t*));
00064   YMP_ALLOC_DIGITS(self, self->len);
00065   memcpy(self->digits, other->digits, sizeof(digit_t)*self->used);
00066 }
00067 
00075 inline void
00076 ymp_reserve_and_initialize_by_digit(mp_ref_t self, size_t len, digit_t d)
00077 {
00078   self->sign = positive_sign;
00079   YMP_ALLOC_DIGITS(self, len);
00080   self->used = 1;
00081   self->digits[0] = d;
00082 }
00083 
00090 void 
00091 ymp_initialize_by_digit(mp_ref_t self, digit_t d)
00092 {
00093   ymp_reserve_and_initialize_by_digit(self, 1, d);
00094 }
00095 
00102 void
00103 ymp_reserve_and_initialize(mp_ref_t self, size_t len)
00104 {
00105   ymp_reserve_and_initialize_by_digit(self, len, 0);
00106 }
00107 
00108 
00117 void
00118 ymp_initialize_by_array(mp_ref_t self, size_t len, const digit_t *array)
00119 {
00120   self->sign = positive_sign;
00121   self->used = len;
00122   YMP_ALLOC_DIGITS(self, len);
00123   memcpy(self->digits, array, len);
00124 } 
00125 
00126 
00136 #define to_sign_check(self, val)                \
00137   if (val >= 0)                                 \
00138     {                                           \
00139       self->sign = positive_sign;               \
00140     }                                           \
00141   else                                          \
00142     {                                           \
00143       self->sign = negative_sign;               \
00144       val = -val;                               \
00145     }
00146 
00155 #define not_to_sign_check(self, val) (void)(self->sign = positive_sign)
00156 
00157 
00158 
00168 #define do_assign_integral_value(type, self, val, allocator, sign_check) \
00169   static const size_t len                                                \
00170     = sizeof(type)/sizeof(digit_t)+!!(sizeof(type)%sizeof(digit_t));     \
00171   size_t i;                                                              \
00172                                                                          \
00173   sign_check(self, val);                                                 \
00174   allocator(self, len);                                                  \
00175                                                                          \
00176   for (i=0; val; ++i)                                                    \
00177     {                                                                    \
00178       self->digits[i] = (digit_t)val & DIGIT_MAX;                        \
00179       val >>= DIGIT_BIT;                                                 \
00180     }                                                                    \
00181   self->used = i;
00182 
00183 
00192 #define define_ymp_initialize_integral_type(type, postfix, sign_check)     \
00193                                                                            \
00199 void ymp_initialize_by_##postfix(mp_ref_t self, type val)                  \
00200 {                                                                          \
00201   do_assign_integral_value(type, self, val, YMP_ALLOC_DIGITS, sign_check); \
00202 }
00203 
00204 define_ymp_initialize_integral_type(signed char, char, to_sign_check);
00205 define_ymp_initialize_integral_type(short, short, to_sign_check);
00206 define_ymp_initialize_integral_type(int, int, to_sign_check);
00207 define_ymp_initialize_integral_type(long, long, to_sign_check);
00208 define_ymp_initialize_integral_type(unsigned char, uchar, not_to_sign_check);
00209 define_ymp_initialize_integral_type(unsigned short, ushort, not_to_sign_check);
00210 define_ymp_initialize_integral_type(unsigned int, uint, not_to_sign_check);
00211 define_ymp_initialize_integral_type(unsigned long, ulong, not_to_sign_check);
00212 #ifdef C99
00213 define_ymp_initialize_integral_type(intmax_t, intmax, to_sign_check);
00214 define_ymp_initialize_integral_type(uintmax_t, uintmax, to_sign_check);
00215 #endif
00216 
00217 
00218 #define do_assign_floating_value(type, sys_suffix, funcname, allocator) \
00219   size_t i, len;                                                        \
00220   type val2;                                                            \
00221                                                                         \
00222   if (!isfinite(val))                                                   \
00223     {                                                                   \
00224       ymp_error(funcname, ": 初期化子が有限値でない");                  \
00225       return;                                                           \
00226     }                                                                   \
00227                                                                         \
00228   if ( val >= 0)                                                        \
00229     {                                                                   \
00230       self->sign = positive_sign;                                       \
00231       val = floor##sys_suffix(val);                                     \
00232     }                                                                   \
00233   else                                                                  \
00234     {                                                                   \
00235       self->sign = negative_sign;                                       \
00236       val = -ceil##sys_suffix(val);                                     \
00237     }                                                                   \
00238                                                                         \
00239   for (len=0, val2=val; val2!=0.0; ++len)                               \
00240     {                                                                   \
00241       val2 = floor##sys_suffix(val2/MULTIPREC_RADIX);                   \
00242     }                                                                   \
00243                                                                         \
00244   allocator(self, len);                                                 \
00245                                                                         \
00246   for (i=0; i<len; ++i)                                                 \
00247     {                                                                   \
00248       self->digits[i] = (digit_t)val;                                   \
00249       val /= MULTIPREC_RADIX;                                           \
00250     }                                                                   \
00251   self->used = len;
00252 
00253 
00262 void ymp_initialize_by_double(mp_ref_t self, double val)
00263 {
00264   do_assign_floating_value(double,, "ymp_initialize_by_double", YMP_ALLOC_DIGITS);
00265 }
00266 
00267 
00268 
00269 
00275 mp_ref_t ymp_dup(mp_cref_t orig)
00276 {
00277   struct multiprec *p = ymp_malloc(sizeof(struct multiprec));
00278   if (!p)
00279     ymp_alloc_error("can't dup struct multiprec", sizeof(struct multiprec));
00280 
00281   ymp_initialize_by_mp(p, orig);
00282   return p;
00283 }
00284 
00294 void
00295 ymp_reserve(mp_ref_t self, size_t len)
00296 {
00297   if (self->len < len) YMP_REALLOC_DIGITS(self, len);
00298 }
00299 
00309 void
00310 ymp_cut_down(mp_ref_t self)
00311 {
00312   YMP_REALLOC_DIGITS(self, self->used);
00313 }
00314 
00335 inline void
00336 ymp_assign_abs(mp_ref_t self, mp_cref_t other)
00337 {
00338   ymp_reserve(self, other->used);
00339   self->used = other->used;
00340   memcpy(self->digits, other->digits, self->used*sizeof(digit_t));
00341 }
00342 
00351 inline void
00352 ymp_assign_abs_digit(mp_ref_t self, digit_t other)
00353 {
00354   ymp_reserve(self, 1);
00355   self->used = 1;
00356   self->digits[0] = other;
00357 }
00358 
00368 inline void
00369 ymp_assign_abs_array(mp_ref_t self, size_t len, const digit_t *array)
00370 {
00371   self->used = len;
00372   ymp_reserve(self, len);
00373   memcpy(self->digits, array, len*sizeof(digit_t));
00374 }
00375 
00388 void
00389 ymp_assign(mp_ref_t self, mp_cref_t other)
00390 {
00391   self->sign = other->sign;
00392   ymp_assign_abs(self, other);
00393 }
00394 
00395 
00403 void
00404 ymp_assign_digit(mp_ref_t self, digit_t other)
00405 {
00406   self->sign = positive_sign;
00407   ymp_assign_abs_digit(self, other);
00408 }
00409 
00418 void
00419 ymp_assign_array(mp_ref_t self, size_t len, const digit_t *array)
00420 {
00421   self->sign = positive_sign;
00422   ymp_assign_abs_array(self, len, array);
00423 } 
00424 
00425 
00426 
00435 #define define_ymp_assign_integral_type(type, postfix, sign_check)      \
00436                                                                         \
00442 void ymp_assign_##postfix(mp_ref_t self, type val)                      \
00443 {                                                                       \
00444   do_assign_integral_value(type, self, val, ymp_reserve, sign_check);   \
00445 }
00446 
00447 define_ymp_assign_integral_type(signed char, char, to_sign_check);
00448 define_ymp_assign_integral_type(short, short, to_sign_check);
00449 define_ymp_assign_integral_type(int, int, to_sign_check);
00450 define_ymp_assign_integral_type(long, long, to_sign_check);
00451 define_ymp_assign_integral_type(unsigned char, uchar, not_to_sign_check);
00452 define_ymp_assign_integral_type(unsigned short, ushort, not_to_sign_check);
00453 define_ymp_assign_integral_type(unsigned int, uint, not_to_sign_check);
00454 define_ymp_assign_integral_type(unsigned long, ulong, not_to_sign_check);
00455 #ifdef C99
00456 define_ymp_assign_integral_type(intmax_t, intmax, to_sign_check);
00457 define_ymp_assign_integral_type(uintmax_t, uintmax, not_to_sign_check);
00458 #endif
00459 
00468 void ymp_assign_double(mp_ref_t self, double val)
00469 {
00470   do_assign_floating_value(double,, "ymp_assign_by_double", ymp_reserve);
00471 }
00472 
00481 void ymp_assign_2exp(mp_ref_t self, size_t pow)
00482 {
00483   size_t n_digits = pow / DIGIT_BIT, n_bits = pow % DIGIT_BIT;
00484 
00485   self->sign = positive_sign;
00486   ymp_reserve(self, n_digits+1);
00487   self->used = n_digits + 1;
00488   memset(self->digits, 0, sizeof(digit_t)*n_digits);
00489   self->digits[n_digits] = 1u << n_bits;
00490 }
00491 
00499 void ymp_swap(mp_ref_t self, mp_ref_t other)
00500 {
00501   enum mp_sign_t tmp_sign;
00502   size_t tmp_size;
00503   digit_t *tmp_digits;
00504 
00505   tmp_sign = self->sign;
00506   self->sign = other->sign;
00507   other->sign = tmp_sign;
00508 
00509   tmp_size = self->len;
00510   self->len = other->len;
00511   other->len = tmp_size;
00512 
00513   tmp_size = self->used;
00514   self->used = other->used;
00515   other->used = tmp_size;
00516 
00517   tmp_digits = self->digits;
00518   self->digits = other->digits;
00519   other->digits = tmp_digits;
00520 }
00521 

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