Back to index

plt-scheme  4.2.1
gmp.h
Go to the documentation of this file.
00001 /* gmp.h -- Definitions for GNU multiple precision functions.
00002 
00003 Copyright (C) 1991, 1993, 1994, 1995, 1996, 1997, 1999, 2000 Free Software
00004 Foundation, Inc.
00005 
00006 This file is part of the GNU MP Library.
00007 
00008 The GNU MP Library is free software; you can redistribute it and/or modify
00009 it under the terms of the GNU Lesser General Public License as published by
00010 the Free Software Foundation; either version 2.1 of the License, or (at your
00011 option) any later version.
00012 
00013 The GNU MP Library is distributed in the hope that it will be useful, but
00014 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
00015 or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
00016 License for more details.
00017 
00018 You should have received a copy of the GNU Lesser General Public License
00019 along with the GNU MP Library; see the file COPYING.LIB.  If not, write to
00020 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
00021 MA 02111-1307, USA. */
00022 
00023 #ifndef __GMP_H__
00024 
00025 #ifndef __GNU_MP__          /* to allow inclusion of both gmp.h and mp.h */
00026 #define __GNU_MP__ 2
00027 #define __need_size_t
00028 #include <stddef.h>
00029 #undef __need_size_t
00030 
00031 #if defined(_MSC_VER)
00032 # ifndef __STDC__
00033 #  define __STDC__ 1
00034 # endif
00035 #endif
00036 
00037 #if defined(__BORLANDC__)
00038 # ifndef __STDC__
00039 #  define __STDC__ 1
00040 # endif
00041 #endif
00042 
00043 #if defined (__mips) && defined (_ABIN32)
00044 /* Force the use of 64-bit limbs for all 64-bit MIPS CPUs if ABI permits.  */
00045 #define _LONG_LONG_LIMB
00046 #endif
00047 
00048 #if (__STDC__-0) || defined (__cplusplus)
00049 #define __gmp_const const
00050 #define __gmp_signed signed
00051 #else
00052 #define __gmp_const
00053 #define __gmp_signed
00054 #endif
00055 
00056 #if defined (__GNUC__)
00057 #define __gmp_inline __inline__
00058 #else
00059 #define __gmp_inline
00060 #endif
00061 
00062 #ifndef _EXTERN_INLINE
00063 #ifdef __GNUC__
00064 #define _EXTERN_INLINE extern __inline__
00065 #else
00066 #define _EXTERN_INLINE static
00067 #endif
00068 #endif
00069 
00070 #ifdef _SHORT_LIMB
00071 typedef unsigned int        mp_limb_t;
00072 typedef int                 mp_limb_signed_t;
00073 #else
00074 #ifdef _LONG_LONG_LIMB
00075 typedef unsigned long long int     mp_limb_t;
00076 typedef long long int              mp_limb_signed_t;
00077 #else
00078 typedef unsigned long int   mp_limb_t;
00079 typedef long int            mp_limb_signed_t;
00080 #endif
00081 #endif
00082 
00083 typedef mp_limb_t *         mp_ptr;
00084 typedef __gmp_const mp_limb_t *    mp_srcptr;
00085 #if defined (_CRAY) && ! defined (_CRAYMPP)
00086 /* plain `int' is much faster (48 bits) */
00087 typedef int                 mp_size_t;
00088 typedef int                 mp_exp_t;
00089 #else
00090 typedef long int            mp_size_t;
00091 typedef long int            mp_exp_t;
00092 #endif
00093 
00094 typedef struct
00095 {
00096   int _mp_alloc;            /* Number of *limbs* allocated and pointed
00097                                to by the _mp_d field.  */
00098   int _mp_size;                    /* abs(_mp_size) is the number of limbs the
00099                                last field points to.  If _mp_size is
00100                                negative this is a negative number.  */
00101   mp_limb_t *_mp_d;         /* Pointer to the limbs.  */
00102 } __mpz_struct;
00103 #endif /* __GNU_MP__ */
00104 
00105 typedef __mpz_struct MP_INT;
00106 typedef __mpz_struct mpz_t[1];
00107 
00108 typedef struct
00109 {
00110   __mpz_struct _mp_num;
00111   __mpz_struct _mp_den;
00112 } __mpq_struct;
00113 
00114 typedef __mpq_struct MP_RAT;
00115 typedef __mpq_struct mpq_t[1];
00116 
00117 typedef struct
00118 {
00119   int _mp_prec;                    /* Max precision, in number of `mp_limb_t's.
00120                                Set by mpf_init and modified by
00121                                mpf_set_prec.  The area pointed to by the
00122                                _mp_d field contains `prec' + 1 limbs.  */
00123   int _mp_size;                    /* abs(_mp_size) is the number of limbs the
00124                                last field points to.  If _mp_size is
00125                                negative this is a negative number.  */
00126   mp_exp_t _mp_exp;         /* Exponent, in the base of `mp_limb_t'.  */
00127   mp_limb_t *_mp_d;         /* Pointer to the limbs.  */
00128 } __mpf_struct;
00129 
00130 /* typedef __mpf_struct MP_FLOAT; */
00131 typedef __mpf_struct mpf_t[1];
00132 
00133 /* Available random number generation algorithms.  */
00134 typedef enum
00135 {
00136   GMP_RAND_ALG_DEFAULT = 0,
00137   GMP_RAND_ALG_LC = GMP_RAND_ALG_DEFAULT /* Linear congruential.  */
00138 } gmp_randalg_t;
00139 
00140 /* Linear congruential data struct.  */
00141 typedef struct {
00142   mpz_t a;                  /* Multiplier. */
00143   unsigned long int c;             /* Adder. */
00144   mpz_t m;                  /* Modulus (valid only if m2exp == 0).  */
00145   unsigned long int m2exp;  /* If != 0, modulus is 2 ^ m2exp.  */
00146 } __gmp_randata_lc;
00147 
00148 /* Random state struct.  */
00149 typedef struct
00150 {
00151   mpz_t seed;               /* Current seed.  */
00152   gmp_randalg_t alg;        /* Algorithm used.  */
00153   union {                   /* Algorithm specific data.  */
00154     __gmp_randata_lc *lc;   /* Linear congruential.  */
00155   } algdata;
00156 } __gmp_randstate_struct;
00157 typedef __gmp_randstate_struct gmp_randstate_t[1];
00158 
00159 /* Types for function declarations in gmp files.  */
00160 /* ??? Should not pollute user name space with these ??? */
00161 typedef __gmp_const __mpz_struct *mpz_srcptr;
00162 typedef __mpz_struct *mpz_ptr;
00163 typedef __gmp_const __mpf_struct *mpf_srcptr;
00164 typedef __mpf_struct *mpf_ptr;
00165 typedef __gmp_const __mpq_struct *mpq_srcptr;
00166 typedef __mpq_struct *mpq_ptr;
00167 
00168 #ifndef _PROTO
00169 #if (__STDC__-0) || defined (__cplusplus) || defined(__BORLANDC__)
00170 #define _PROTO(x) x
00171 #else
00172 #define _PROTO(x) ()
00173 #endif
00174 #endif
00175 
00176 #ifndef __MPN
00177 /* Really use `defined (__STDC__)' here; we want it to be true for Sun C */
00178 #if defined (__STDC__) || defined (__cplusplus) || defined(__BORLANDC__)
00179 #define __MPN(x) scheme_gmpn_##x
00180 #else
00181 #define __MPN(x) scheme_gmpn_x
00182 #endif
00183 #endif
00184 
00185 #if defined (FILE) || defined (H_STDIO) || defined (_H_STDIO) \
00186  || defined (_STDIO_H) || defined (_STDIO_H_) || defined (__STDIO_H__) \
00187  || defined (_STDIO_INCLUDED) || defined (__dj_include_stdio_h_)
00188 #define _GMP_H_HAVE_FILE 1
00189 #endif
00190 
00191 #if defined (__cplusplus)
00192 extern "C" {
00193 #endif
00194 
00195 #define mp_set_memory_functions __gmp_set_memory_functions
00196 void mp_set_memory_functions _PROTO ((void *(*) (size_t),
00197                                   void *(*) (void *, size_t, size_t),
00198                                   void (*) (void *, size_t)));
00199 
00200 #define mp_bits_per_limb __gmp_bits_per_limb
00201 extern __gmp_const int mp_bits_per_limb;
00202 
00203 #if defined (__cplusplus)
00204 }
00205 #endif
00206 
00207 
00208 /************ Low level positive-integer (i.e. N) routines.  ************/
00209 
00210 /* This is ugly, but we need to make user calls reach the prefixed function. */
00211 #define mpn_add                    __MPN(add)
00212 #define mpn_add_1           __MPN(add_1)
00213 #define mpn_add_n           __MPN(add_n)
00214 #define mpn_add_nc          __MPN(add_nc)
00215 #define mpn_addmul_1        __MPN(addmul_1)
00216 #define mpn_addsub_n        __MPN(addsub_n)
00217 #define mpn_addsub_nc              __MPN(addsub_nc)
00218 /* #define mpn_and_n        __MPN(and_n) */
00219 /* #define mpn_andn_n              __MPN(andn_n) */
00220 #define mpn_bdivmod         __MPN(bdivmod)
00221 #define mpn_cmp                    __MPN(cmp)
00222 /* #define mpn_com_n        __MPN(com_n) */
00223 #define mpn_copyd           __MPN(copyd)
00224 #define mpn_copyi           __MPN(copyi)
00225 #define mpn_divrem          __MPN(divrem)
00226 #define mpn_divrem_1        __MPN(divrem_1)
00227 #define mpn_divrem_2        __MPN(divrem_2)
00228 #define mpn_dump            __MPN(dump)
00229 #define mpn_gcd                    __MPN(gcd)
00230 #define mpn_gcd_1           __MPN(gcd_1)
00231 #define mpn_gcdext          __MPN(gcdext)
00232 #define mpn_get_str         __MPN(get_str)
00233 #define mpn_hamdist         __MPN(hamdist)
00234 #define mpn_invert_limb     __MPN(invert_limb)
00235 /* #define mpn_ior_n        __MPN(ior_n) */
00236 /* #define mpn_iorn_n              __MPN(iorn_n) */
00237 /* #define mpn_kara_mul_n   __MPN(kara_mul_n)  internal */
00238 /* #define mpn_kara_sqr_n   __MPN(kara_sqr_n)  internal */
00239 #define mpn_lshift          __MPN(lshift)
00240 #define mpn_lshiftc         __MPN(lshiftc)
00241 #define mpn_mod_1           __MPN(mod_1)
00242 #define mpn_mul                    __MPN(mul)
00243 #define mpn_mul_1           __MPN(mul_1)
00244 #define mpn_mul_basecase    __MPN(mul_basecase)
00245 #define mpn_mul_n           __MPN(mul_n)
00246 #define mpn_perfect_square_p       __MPN(perfect_square_p)
00247 #define mpn_popcount        __MPN(popcount)
00248 #define mpn_preinv_mod_1    __MPN(preinv_mod_1)
00249 /* #define mpn_nand_n              __MPN(nand_n) */
00250 /* #define mpn_nior_n              __MPN(nior_n) */
00251 #define mpn_random          __MPN(random)
00252 #define mpn_random2         __MPN(random2)
00253 #define mpn_rshift          __MPN(rshift)
00254 #define mpn_rshiftc         __MPN(rshiftc)
00255 #define mpn_scan0           __MPN(scan0)
00256 #define mpn_scan1           __MPN(scan1)
00257 #define mpn_set_str         __MPN(set_str)
00258 #define mpn_sqr_basecase    __MPN(sqr_basecase)
00259 #define mpn_sqr_n           __MPN(sqr_n)
00260 #define mpn_sqrtrem         __MPN(sqrtrem)
00261 #define mpn_sub                    __MPN(sub)
00262 #define mpn_sub_1           __MPN(sub_1)
00263 #define mpn_sub_n           __MPN(sub_n)
00264 #define mpn_sub_nc          __MPN(sub_nc)
00265 #define mpn_submul_1        __MPN(submul_1)
00266 /* #define mpn_toom3_mul_n         __MPN(toom3_mul_n)  internal */
00267 /* #define mpn_toom3_sqr_n         __MPN(toom3_sqr_n)  internal */
00268 /* #define mpn_xnor_n              __MPN(xnor_n) */
00269 /* #define mpn_xor_n        __MPN(xor_n) */
00270 
00271 #ifdef MZ_PRECISE_GC
00272 # define XFORM_GMP_NONGCING XFORM_NONGCING
00273 #else
00274 # define XFORM_GMP_NONGCING 
00275 #endif
00276 
00277 #if defined (__cplusplus)
00278 extern "C" {
00279 #endif
00280 mp_limb_t mpn_add _PROTO ((mp_ptr, mp_srcptr, mp_size_t, mp_srcptr,mp_size_t));
00281 mp_limb_t mpn_add_1 _PROTO ((mp_ptr, mp_srcptr, mp_size_t, mp_limb_t));
00282 mp_limb_t mpn_add_n _PROTO ((mp_ptr, mp_srcptr, mp_srcptr, mp_size_t));
00283 mp_limb_t mpn_add_nc _PROTO ((mp_ptr, mp_srcptr, mp_srcptr, mp_size_t, mp_limb_t));
00284 
00285 mp_limb_t mpn_addmul_1 _PROTO ((mp_ptr, mp_srcptr, mp_size_t, mp_limb_t));
00286 
00287 #define mpn_addmul_1c  __MPN(addmul_1c)
00288 mp_limb_t mpn_addmul_1c _PROTO ((mp_ptr, mp_srcptr, mp_size_t, mp_limb_t, mp_limb_t));
00289 
00290 mp_limb_t mpn_addsub_n _PROTO ((mp_ptr, mp_ptr, mp_srcptr, mp_srcptr, mp_size_t));
00291 mp_limb_t mpn_bdivmod _PROTO ((mp_ptr, mp_ptr, mp_size_t, mp_srcptr, mp_size_t, unsigned long int));
00292 XFORM_GMP_NONGCING int mpn_cmp _PROTO ((mp_srcptr, mp_srcptr, mp_size_t));
00293 
00294 #define mpn_divexact_by3(dst, src, size)  mpn_divexact_by3c (dst, src, size, 0)
00295 
00296 #define mpn_divexact_by3c  __MPN(divexact_by3c)
00297 mp_limb_t mpn_divexact_by3c _PROTO ((mp_ptr dst, mp_srcptr src,
00298                                      mp_size_t size, mp_limb_t carry));
00299 
00300 #define mpn_divmod_1(qp,np,nsize,dlimb) mpn_divrem_1 (qp,0,np,nsize,dlimb)
00301 
00302 mp_limb_t mpn_divrem _PROTO((mp_ptr, mp_size_t, mp_ptr, mp_size_t, mp_srcptr, mp_size_t));
00303 
00304 mp_limb_t mpn_divrem_1 _PROTO ((mp_ptr, mp_size_t, mp_srcptr, mp_size_t, mp_limb_t));
00305 
00306 #define mpn_divrem_1c  __MPN(divrem_1c)
00307 mp_limb_t mpn_divrem_1c _PROTO ((mp_ptr, mp_size_t, mp_srcptr, mp_size_t,
00308                                  mp_limb_t, mp_limb_t));
00309 
00310 mp_limb_t mpn_divrem_2 _PROTO ((mp_ptr, mp_size_t, mp_ptr, mp_size_t, mp_srcptr));
00311 void mpn_dump _PROTO ((mp_srcptr, mp_size_t));
00312 mp_size_t mpn_gcd _PROTO ((mp_ptr, mp_ptr, mp_size_t, mp_ptr, mp_size_t));
00313 mp_limb_t mpn_gcd_1 _PROTO ((mp_srcptr, mp_size_t, mp_limb_t));
00314 mp_size_t mpn_gcdext _PROTO ((mp_ptr, mp_ptr, mp_size_t *, mp_ptr, mp_size_t, mp_ptr, mp_size_t));
00315 size_t mpn_get_str _PROTO ((unsigned char *, int, mp_ptr, mp_size_t));
00316 unsigned long int mpn_hamdist _PROTO ((mp_srcptr, mp_srcptr, mp_size_t));
00317 
00318 #define mpn_jacobi_base __MPN(jacobi_base)
00319 int mpn_jacobi_base _PROTO ((mp_limb_t a, mp_limb_t b, int result_bit1));
00320 
00321 mp_limb_t mpn_lshift _PROTO ((mp_ptr, mp_srcptr, mp_size_t, unsigned int));
00322 mp_limb_t mpn_mod_1 _PROTO ((mp_srcptr, mp_size_t, mp_limb_t));
00323 
00324 #define mpn_mod_1c  __MPN(mod_1c)
00325 mp_limb_t mpn_mod_1c _PROTO ((mp_srcptr, mp_size_t, mp_limb_t, mp_limb_t));
00326 
00327 #define mpn_mod_1_rshift __MPN(mod_1_rshift)
00328 mp_limb_t mpn_mod_1_rshift _PROTO ((mp_srcptr, mp_size_t, unsigned,mp_limb_t));
00329 
00330 mp_limb_t mpn_mul _PROTO ((mp_ptr, mp_srcptr, mp_size_t, mp_srcptr, mp_size_t));
00331 mp_limb_t mpn_mul_1 _PROTO ((mp_ptr, mp_srcptr, mp_size_t, mp_limb_t));
00332 
00333 #define mpn_mul_1c  __MPN(mul_1c)
00334 mp_limb_t mpn_mul_1c _PROTO ((mp_ptr, mp_srcptr, mp_size_t, mp_limb_t, mp_limb_t));
00335 
00336 void mpn_mul_basecase _PROTO ((mp_ptr, mp_srcptr, mp_size_t, mp_srcptr, mp_size_t));
00337 void mpn_mul_n _PROTO ((mp_ptr, mp_srcptr, mp_srcptr, mp_size_t));
00338 int mpn_perfect_square_p _PROTO ((mp_srcptr, mp_size_t));
00339 unsigned long int mpn_popcount _PROTO ((mp_srcptr, mp_size_t));
00340 mp_limb_t mpn_preinv_mod_1 _PROTO ((mp_srcptr, mp_size_t, mp_limb_t, mp_limb_t));
00341 void mpn_random _PROTO ((mp_ptr, mp_size_t));
00342 void mpn_random2 _PROTO ((mp_ptr, mp_size_t));
00343 mp_limb_t mpn_rshift _PROTO ((mp_ptr, mp_srcptr, mp_size_t, unsigned int));
00344 unsigned long int mpn_scan0 _PROTO ((mp_srcptr, unsigned long int));
00345 unsigned long int mpn_scan1 _PROTO ((mp_srcptr, unsigned long int));
00346 mp_size_t mpn_set_str _PROTO ((mp_ptr, __gmp_const unsigned char *, size_t, int));
00347 void mpn_sqr_n _PROTO ((mp_ptr, mp_srcptr, mp_size_t));
00348 void mpn_sqr_basecase _PROTO ((mp_ptr, mp_srcptr, mp_size_t));
00349 mp_size_t mpn_sqrtrem _PROTO ((mp_ptr, mp_ptr, mp_srcptr, mp_size_t));
00350 mp_limb_t mpn_sub _PROTO ((mp_ptr, mp_srcptr, mp_size_t, mp_srcptr,mp_size_t));
00351 mp_limb_t mpn_sub_1 _PROTO ((mp_ptr, mp_srcptr, mp_size_t, mp_limb_t));
00352 mp_limb_t mpn_sub_n _PROTO ((mp_ptr, mp_srcptr, mp_srcptr, mp_size_t));
00353 mp_limb_t mpn_sub_nc _PROTO ((mp_ptr, mp_srcptr, mp_srcptr, mp_size_t, mp_limb_t));
00354 mp_limb_t mpn_submul_1 _PROTO ((mp_ptr, mp_srcptr, mp_size_t, mp_limb_t));
00355 
00356 #define mpn_submul_1c  __MPN(submul_1c)
00357 mp_limb_t mpn_submul_1c _PROTO ((mp_ptr, mp_srcptr, mp_size_t, mp_limb_t, mp_limb_t));
00358 
00359 #define mpn_tdiv_qr  __MPN(tdiv_qr)
00360 void mpn_tdiv_qr _PROTO ((mp_ptr, mp_ptr, mp_size_t, mp_srcptr, mp_size_t, mp_srcptr, mp_size_t));
00361 
00362 #if defined (__cplusplus)
00363 }
00364 #endif
00365 
00366 #define mpn_incr_u(p,incr) \
00367   do { mp_limb_t __x; mp_ptr __p = p;                   \
00368     __x = *__p + incr;                                  \
00369     *__p = __x;                                         \
00370     if (__x < incr)                              \
00371       while (++(*(++__p)) == 0) {}               \
00372   } while (0)
00373 
00374 #define mpn_decr_u(p,incr) \
00375   do { mp_limb_t __x; mp_ptr __p = p;                   \
00376     __x = *__p;                                         \
00377     *__p = __x - incr;                                  \
00378     if (__x < incr)                              \
00379       while ((*(++__p))-- == 0)    {}                   \
00380   } while (0)
00381 
00382 #if (defined (__GNUC__) || defined (_FORCE_INLINES)) && !defined(PALMOS_STUFF)
00383 _EXTERN_INLINE mp_limb_t
00384 #if (__STDC__-0) || defined (__cplusplus) || defined(__BORLANDC__)
00385 mpn_add_1 (register mp_ptr res_ptr,
00386           register mp_srcptr s1_ptr,
00387           register mp_size_t s1_size,
00388           register mp_limb_t s2_limb)
00389 #else
00390 mpn_add_1 (res_ptr, s1_ptr, s1_size, s2_limb)
00391      register mp_ptr res_ptr;
00392      register mp_srcptr s1_ptr;
00393      register mp_size_t s1_size;
00394      register mp_limb_t s2_limb;
00395 #endif
00396 {
00397   register mp_limb_t x;
00398 
00399   x = *s1_ptr++;
00400   s2_limb = x + s2_limb;
00401   *res_ptr++ = s2_limb;
00402   if (s2_limb < x)
00403     {
00404       while (--s1_size != 0)
00405        {
00406          x = *s1_ptr++ + 1;
00407          *res_ptr++ = x;
00408          if (x != 0)
00409            goto fin;
00410        }
00411 
00412       return 1;
00413     }
00414 
00415  fin:
00416   if (res_ptr != s1_ptr)
00417     {
00418       mp_size_t i;
00419       for (i = 0; i < s1_size - 1; i++) {
00420        res_ptr[i] = s1_ptr[i];
00421       }
00422     }
00423   return 0;
00424 }
00425 
00426 _EXTERN_INLINE mp_limb_t
00427 #if (__STDC__-0) || defined (__cplusplus) || defined(__BORLANDC__)
00428 mpn_add (register mp_ptr res_ptr,
00429         register mp_srcptr s1_ptr,
00430         register mp_size_t s1_size,
00431         register mp_srcptr s2_ptr,
00432         register mp_size_t s2_size)
00433 #else
00434 mpn_add (res_ptr, s1_ptr, s1_size, s2_ptr, s2_size)
00435      register mp_ptr res_ptr;
00436      register mp_srcptr s1_ptr;
00437      register mp_size_t s1_size;
00438      register mp_srcptr s2_ptr;
00439      register mp_size_t s2_size;
00440 #endif
00441 {
00442   mp_limb_t cy_limb = 0;
00443 
00444   if (s2_size != 0)
00445     cy_limb = mpn_add_n (res_ptr, s1_ptr, s2_ptr, s2_size);
00446 
00447   if (s1_size - s2_size != 0)
00448     cy_limb = mpn_add_1 (res_ptr + s2_size,
00449                       s1_ptr + s2_size,
00450                       s1_size - s2_size,
00451                       cy_limb);
00452   return cy_limb;
00453 }
00454 
00455 _EXTERN_INLINE mp_limb_t
00456 #if (__STDC__-0) || defined (__cplusplus) || defined(__BORLANDC__)
00457 mpn_sub_1 (register mp_ptr res_ptr,
00458           register mp_srcptr s1_ptr,
00459           register mp_size_t s1_size,
00460           register mp_limb_t s2_limb)
00461 #else
00462 mpn_sub_1 (res_ptr, s1_ptr, s1_size, s2_limb)
00463      register mp_ptr res_ptr;
00464      register mp_srcptr s1_ptr;
00465      register mp_size_t s1_size;
00466      register mp_limb_t s2_limb;
00467 #endif
00468 {
00469   register mp_limb_t x;
00470 
00471   x = *s1_ptr++;
00472   s2_limb = x - s2_limb;
00473   *res_ptr++ = s2_limb;
00474   if (s2_limb > x)
00475     {
00476       while (--s1_size != 0)
00477        {
00478          x = *s1_ptr++;
00479          *res_ptr++ = x - 1;
00480          if (x != 0)
00481            goto fin;
00482        }
00483 
00484       return 1;
00485     }
00486 
00487  fin:
00488   if (res_ptr != s1_ptr)
00489     {
00490       mp_size_t i;
00491       for (i = 0; i < s1_size - 1; i++) {
00492        res_ptr[i] = s1_ptr[i];
00493       }
00494     }
00495   return 0;
00496 }
00497 
00498 _EXTERN_INLINE mp_limb_t
00499 #if (__STDC__-0) || defined (__cplusplus) || defined(__BORLANDC__)
00500 mpn_sub (register mp_ptr res_ptr,
00501         register mp_srcptr s1_ptr,
00502         register mp_size_t s1_size,
00503         register mp_srcptr s2_ptr,
00504         register mp_size_t s2_size)
00505 #else
00506 mpn_sub (res_ptr, s1_ptr, s1_size, s2_ptr, s2_size)
00507      register mp_ptr res_ptr;
00508      register mp_srcptr s1_ptr;
00509      register mp_size_t s1_size;
00510      register mp_srcptr s2_ptr;
00511      register mp_size_t s2_size;
00512 #endif
00513 {
00514   mp_limb_t cy_limb = 0;
00515 
00516   if (s2_size != 0)
00517     cy_limb = mpn_sub_n (res_ptr, s1_ptr, s2_ptr, s2_size);
00518 
00519   if (s1_size - s2_size != 0)
00520     cy_limb = mpn_sub_1 (res_ptr + s2_size,
00521                       s1_ptr + s2_size,
00522                       s1_size - s2_size,
00523                       cy_limb);
00524   return cy_limb;
00525 }
00526 #endif /* __GNUC__ */
00527 
00528 /* Allow faster testing for negative, zero, and positive.  */
00529 #define mpz_sgn(Z) ((Z)->_mp_size < 0 ? -1 : (Z)->_mp_size > 0)
00530 #define mpf_sgn(F) ((F)->_mp_size < 0 ? -1 : (F)->_mp_size > 0)
00531 #define mpq_sgn(Q) ((Q)->_mp_num._mp_size < 0 ? -1 : (Q)->_mp_num._mp_size > 0)
00532 
00533 /* When using GCC, optimize certain common comparisons.  */
00534 #if defined (__GNUC__)
00535 #define mpz_cmp_ui(Z,UI) \
00536   (__builtin_constant_p (UI) && (UI) == 0                      \
00537    ? mpz_sgn (Z) : _mpz_cmp_ui (Z,UI))
00538 #define mpz_cmp_si(Z,SI) \
00539   (__builtin_constant_p (SI) && (SI) == 0 ? mpz_sgn (Z)               \
00540    : __builtin_constant_p (SI) && (SI) > 0                            \
00541     ? _mpz_cmp_ui (Z, (unsigned long int) SI)                         \
00542    : _mpz_cmp_si (Z,SI))
00543 #define mpq_cmp_ui(Q,NUI,DUI) \
00544   (__builtin_constant_p (NUI) && (NUI) == 0                           \
00545    ? mpq_sgn (Q) : _mpq_cmp_ui (Q,NUI,DUI))
00546 #else
00547 #define mpz_cmp_ui(Z,UI) _mpz_cmp_ui (Z,UI)
00548 #define mpz_cmp_si(Z,UI) _mpz_cmp_si (Z,UI)
00549 #define mpq_cmp_ui(Q,NUI,DUI) _mpq_cmp_ui (Q,NUI,DUI)
00550 #endif
00551 
00552 
00553 /* Using "&" rather than "&&" means these can come out branch-free.  Every
00554    mpz_t has at least one limb allocated, so fetching the low limb is always
00555    allowed.  */
00556 #define mpz_odd_p(z)   ((int) ((z)->_mp_size != 0) & (int) (z)->_mp_d[0])
00557 #define mpz_even_p(z)  (! mpz_odd_p (z))
00558 
00559 
00560 /* Allow direct user access to numerator and denominator of a mpq_t object.  */
00561 #define mpq_numref(Q) (&((Q)->_mp_num))
00562 #define mpq_denref(Q) (&((Q)->_mp_den))
00563 
00564 
00565 /* Compatibility with GMP 2 and earlier. */
00566 #define mpn_divmod(qp,np,nsize,dp,dsize) mpn_divrem (qp,0,np,nsize,dp,dsize)
00567 
00568 /* Compatibility with GMP 1.  */
00569 #define mpz_mdiv     mpz_fdiv_q
00570 #define mpz_mdivmod  mpz_fdiv_qr
00571 #define mpz_mmod     mpz_fdiv_r
00572 #define mpz_mdiv_ui  mpz_fdiv_q_ui
00573 #define mpz_mdivmod_ui(q,r,n,d) \
00574   ((r == 0) ? mpz_fdiv_q_ui (q,n,d) : mpz_fdiv_qr_ui (q,r,n,d))
00575 #define mpz_mmod_ui(r,n,d) \
00576   ((r == 0) ? mpz_fdiv_ui (n,d) : mpz_fdiv_r_ui (r,n,d))
00577 
00578 /* Useful synonyms, but not quite compatible with GMP 1.  */
00579 #define mpz_div             mpz_fdiv_q
00580 #define mpz_divmod   mpz_fdiv_qr
00581 #define mpz_div_ui   mpz_fdiv_q_ui
00582 #define mpz_divmod_ui       mpz_fdiv_qr_ui
00583 #define mpz_mod_ui   mpz_fdiv_r_ui
00584 #define mpz_div_2exp mpz_fdiv_q_2exp
00585 #define mpz_mod_2exp mpz_fdiv_r_2exp
00586 
00587 #define gmp_errno __gmp_errno
00588 extern int gmp_errno;
00589 
00590 enum
00591 {
00592   GMP_ERROR_NONE = 0,
00593   GMP_ERROR_UNSUPPORTED_ARGUMENT = 1,
00594   GMP_ERROR_DIVISION_BY_ZERO = 2,
00595   GMP_ERROR_SQRT_OF_NEGATIVE = 4,
00596   GMP_ERROR_INVALID_ARGUMENT = 8,
00597   GMP_ERROR_ALLOCATE = 16,
00598   GMP_ERROR_BAD_STRING = 32,
00599   GMP_ERROR_UNUSED_ERROR
00600 };
00601 
00602 /* Note: major version number is in mp.h too */
00603 #define __GNU_MP_VERSION 3
00604 #define __GNU_MP_VERSION_MINOR 1
00605 #define __GNU_MP_VERSION_PATCHLEVEL 1
00606 
00607 #define gmp_version __gmp_version
00608 extern __gmp_const char *gmp_version;
00609 
00610 #define __GMP_H__
00611 #endif /* __GMP_H__ */