PageRenderTime 52ms CodeModel.GetById 13ms app.highlight 34ms RepoModel.GetById 1ms app.codeStats 0ms

/src/gmpy_mpfr.h

http://gmpy.googlecode.com/
C++ Header | 421 lines | 353 code | 32 blank | 36 comment | 52 complexity | 3e6c2c1539167cda39ba9cb83c4fe684 MD5 | raw file
  1/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  2 * gmpy_mpfr.h                                                             *
  3 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  4 * Python interface to the GMP or MPIR, MPFR, and MPC multiple precision   *
  5 * libraries.                                                              *
  6 *                                                                         *
  7 * Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,               *
  8 *           2008, 2009 Alex Martelli                                      *
  9 *                                                                         *
 10 * Copyright 2008, 2009, 2010, 2011, 2012, 2013 Case Van Horsen            *
 11 *                                                                         *
 12 * This file is part of GMPY2.                                             *
 13 *                                                                         *
 14 * GMPY2 is free software: you can redistribute it and/or modify it under  *
 15 * the terms of the GNU Lesser General Public License as published by the  *
 16 * Free Software Foundation, either version 3 of the License, or (at your  *
 17 * option) any later version.                                              *
 18 *                                                                         *
 19 * GMPY2 is distributed in the hope that it will be useful, but WITHOUT    *
 20 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or   *
 21 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public    *
 22 * License for more details.                                               *
 23 *                                                                         *
 24 * You should have received a copy of the GNU Lesser General Public        *
 25 * License along with GMPY2; if not, see <http://www.gnu.org/licenses/>    *
 26 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
 27
 28
 29/* gmpy_mpfr C API extension header file.
 30 *
 31 * Provide interface to the MPFR (Multiple Precision Floating-point with
 32 * Rounding) library.
 33 *
 34 * Version 2.00, April 2011 (created) casevh
 35 */
 36
 37#ifndef GMPY_MPFR_H
 38#define GMPY_MPFR_H
 39
 40#ifdef __cplusplus
 41extern "C" {
 42#endif
 43
 44
 45#if !defined(FLT_RADIX) || (FLT_RADIX!=2)
 46#   error "FLT_RADIX undefined or != 2, GMPY2 is confused. :("
 47#endif
 48
 49#if defined(MS_WIN32) && defined(_MSC_VER)
 50#  pragma comment(lib,"mpfr.lib")
 51#endif
 52
 53typedef struct {
 54    PyObject_HEAD
 55    mpfr_t f;
 56    Py_hash_t hash_cache;
 57    int rc;
 58    int round_mode;
 59} PympfrObject;
 60
 61#define GMPY_DIVZERO(msg) PyErr_SetString(GMPyExc_DivZero, msg)
 62#define GMPY_INEXACT(msg) PyErr_SetString(GMPyExc_Inexact, msg)
 63#define GMPY_INVALID(msg) PyErr_SetString(GMPyExc_Invalid, msg)
 64#define GMPY_OVERFLOW(msg) PyErr_SetString(GMPyExc_Overflow, msg)
 65#define GMPY_UNDERFLOW(msg) PyErr_SetString(GMPyExc_Underflow, msg)
 66#define GMPY_ERANGE(msg) PyErr_SetString(GMPyExc_Erange, msg)
 67#define GMPY_EXPBOUND(msg) PyErr_SetString(GMPyExc_ExpBound, msg)
 68
 69#define CHECK_UNDERFLOW(msg) \
 70    if (mpfr_underflow_p() && context->ctx.trap_underflow) { \
 71        GMPY_UNDERFLOW(msg); \
 72        goto done; \
 73    }
 74
 75#define MPFR_CHECK_UNDERFLOW(mpfrt, msg) \
 76    if (mpfr_zero_p(mpfrt->f) && mpfrt->rc) { \
 77        context->ctx.underflow = 1; \
 78        if (context->ctx.trap_underflow) { \
 79            GMPY_UNDERFLOW(msg); \
 80            goto done; \
 81        } \
 82    }
 83
 84#define CHECK_OVERFLOW(msg) \
 85    if (mpfr_overflow_p() && context->ctx.trap_overflow) { \
 86        GMPY_OVERFLOW(msg); \
 87        goto done; \
 88    }
 89
 90#define MPFR_CHECK_OVERFLOW(mpfrt, msg) \
 91    if (mpfr_inf_p(mpfrt->f)) { \
 92        context->ctx.overflow = 1; \
 93        if (context->ctx.trap_overflow) { \
 94            GMPY_OVERFLOW(msg); \
 95            goto done; \
 96        } \
 97    }
 98
 99#define CHECK_INEXACT(msg) \
100    if (mpfr_inexflag_p() && context->ctx.trap_inexact) { \
101        GMPY_INEXACT(msg); \
102        goto done; \
103    }
104
105#define MPFR_CHECK_INEXACT(mpfrt, msg) \
106    if (mpfrt->rc)  { \
107        context->ctx.inexact = 1; \
108        if (context->ctx.trap_inexact) { \
109            GMPY_INEXACT(msg); \
110            goto done; \
111        } \
112    }
113
114#define CHECK_INVALID(msg) \
115    if (mpfr_nanflag_p() && context->ctx.trap_invalid) { \
116        GMPY_INVALID(msg); \
117        goto done; \
118    }
119
120#define MPFR_CHECK_INVALID(mpfrt, msg) \
121    if (mpfr_nan_p(mpfrt->f)) { \
122        context->ctx.invalid = 1; \
123        if (context->ctx.trap_invalid) { \
124            GMPY_INVALID(msg); \
125            goto done; \
126        } \
127    }
128
129#define CHECK_ERANGE(msg) \
130    if (mpfr_erangeflag_p() && context->ctx.trap_erange) { \
131        GMPY_ERANGE(msg); \
132        goto done; \
133    }
134
135#define CHECK_DIVBY0(msg) \
136    if (mpfr_divby0_p() && context->ctx.trap_divzero) { \
137        GMPY_DIVZERO(msg); \
138        goto done; \
139    }
140
141#define MERGE_FLAGS \
142    context->ctx.underflow |= mpfr_underflow_p(); \
143    context->ctx.overflow |= mpfr_overflow_p(); \
144    context->ctx.invalid |= mpfr_nanflag_p(); \
145    context->ctx.inexact |= mpfr_inexflag_p(); \
146    context->ctx.erange |= mpfr_erangeflag_p(); \
147    context->ctx.divzero |= mpfr_divby0_p();
148
149#define CHECK_FLAGS(NAME) \
150    CHECK_DIVBY0("'mpfr' division by zero in "NAME); \
151    CHECK_INVALID("'mpfr' invalid operation in "NAME); \
152    CHECK_UNDERFLOW("'mpfr' underflow in "NAME); \
153    CHECK_OVERFLOW("'mpfr' overflow in "NAME); \
154    CHECK_INEXACT("'mpfr' inexact result in "NAME); \
155
156#define MPFR_CHECK_FLAGS(mpfrt, NAME) \
157    CHECK_DIVBY0(mpfrt, "'mpfr' division by zero in "NAME); \
158    CHECK_INVALID(mpfrt, "'mpfr' invalid operation in "NAME); \
159    CHECK_UNDERFLOW(mpfrt, "'mpfr' underflow in "NAME); \
160    CHECK_OVERFLOW(mpfrt, "'mpfr' overflow in "NAME); \
161    CHECK_INEXACT(mpfrt, "'mpfr' inexact result in "NAME); \
162
163#define SUBNORMALIZE(NAME) \
164    if (context->ctx.subnormalize) \
165        NAME->rc = mpfr_subnormalize(NAME->f, NAME->rc, context->ctx.mpfr_round);
166
167#define MPFR_SUBNORMALIZE(mpfrt) \
168    if (context->ctx.subnormalize) \
169        mpfrt->rc = mpfr_subnormalize(mpfrt->f, mpfrt->rc, context->ctx.mpfr_round);
170
171#define MPFR_CLEANUP_SELF(NAME) \
172    SUBNORMALIZE(result); \
173    MERGE_FLAGS; \
174    CHECK_DIVBY0("'mpfr' division by zero in "NAME); \
175    CHECK_INVALID("'mpfr' invalid operation in "NAME); \
176    CHECK_UNDERFLOW("'mpfr' underflow in "NAME); \
177    CHECK_OVERFLOW("'mpfr' overflow in "NAME); \
178    CHECK_INEXACT("'mpfr' inexact result in "NAME); \
179  done: \
180    Py_DECREF(self); \
181    if (PyErr_Occurred()) { \
182        Py_XDECREF((PyObject*)result); \
183        result = NULL; \
184    } \
185    return (PyObject*)result;
186
187#define MPFR_CLEANUP_SELF_OTHER(NAME) \
188    SUBNORMALIZE(result); \
189    MERGE_FLAGS; \
190    CHECK_DIVBY0("'mpfr' division by zero in "NAME); \
191    CHECK_INVALID("'mpfr' invalid operation in "NAME); \
192    CHECK_UNDERFLOW("'mpfr' underflow in "NAME); \
193    CHECK_OVERFLOW("'mpfr' overflow in "NAME); \
194    CHECK_INEXACT("'mpfr' inexact result in "NAME); \
195  done: \
196    Py_DECREF(self); \
197    Py_DECREF(other); \
198    if (PyErr_Occurred()) { \
199        Py_XDECREF((PyObject*)result); \
200        result = NULL; \
201    } \
202    return (PyObject*)result;
203
204#define MPFR_CLEANUP_RF(NAME) \
205    SUBNORMALIZE(rf); \
206    MERGE_FLAGS; \
207    if (mpfr_nanflag_p() && context->ctx.trap_invalid) { \
208        GMPY_INVALID("'mpfr' invalid operation in " #NAME); \
209        Py_DECREF((PyObject*)rf); \
210        return NULL; \
211    } \
212    if (mpfr_divby0_p() && context->ctx.trap_divzero) { \
213        GMPY_DIVZERO("'mpfr' division by zero in " #NAME); \
214        Py_DECREF((PyObject*)rf); \
215        return NULL; \
216    } \
217    if (mpfr_underflow_p() && context->ctx.trap_underflow) { \
218        GMPY_UNDERFLOW("'mpfr' underflow in " #NAME); \
219        Py_DECREF((PyObject*)rf); \
220        return NULL; \
221    } \
222    if (mpfr_overflow_p() && context->ctx.trap_overflow) { \
223        GMPY_OVERFLOW("'mpfr' overflow in " #NAME); \
224        Py_DECREF((PyObject*)rf); \
225        return NULL; \
226    } \
227    if (mpfr_inexflag_p() && context->ctx.trap_inexact) { \
228        GMPY_INEXACT("'mpfr' inexact result in " #NAME); \
229        Py_DECREF((PyObject*)rf); \
230        return NULL; \
231    } \
232    return (PyObject*)rf;
233
234#define MPFR_CLEANUP_RESULT(NAME) \
235    SUBNORMALIZE(result); \
236    MERGE_FLAGS; \
237    if (mpfr_nanflag_p() && context->ctx.trap_invalid) { \
238        GMPY_INVALID("'mpfr' invalid operation in " #NAME); \
239        Py_DECREF((PyObject*)result); \
240        return NULL; \
241    } \
242    if (mpfr_divby0_p() && context->ctx.trap_divzero) { \
243        GMPY_DIVZERO("'mpfr' division by zero in " #NAME); \
244        Py_DECREF((PyObject*)result); \
245        return NULL; \
246    } \
247    if (mpfr_underflow_p() && context->ctx.trap_underflow) { \
248        GMPY_UNDERFLOW("'mpfr' underflow in " #NAME); \
249        Py_DECREF((PyObject*)result); \
250        return NULL; \
251    } \
252    if (mpfr_overflow_p() && context->ctx.trap_overflow) { \
253        GMPY_OVERFLOW("'mpfr' overflow in " #NAME); \
254        Py_DECREF((PyObject*)result); \
255        return NULL; \
256    } \
257    if (mpfr_inexflag_p() && context->ctx.trap_inexact) { \
258        GMPY_INEXACT("'mpfr' inexact result in " #NAME); \
259        Py_DECREF((PyObject*)result); \
260        return NULL; \
261    } \
262    return (PyObject*)result;
263
264static PyTypeObject Pympfr_Type;
265#define Pympfr_AS_MPFR(obj) (((PympfrObject *)(obj))->f)
266#define Pympfr_Check(v) (((PyObject*)v)->ob_type == &Pympfr_Type)
267/* Verify that an object is an mpfr and the exponent is valid */
268#define Pympfr_CheckAndExp(v) \
269    (Pympfr_Check(v) && \
270        (mpfr_zero_p(Pympfr_AS_MPFR(v)) || \
271            (mpfr_regular_p(Pympfr_AS_MPFR(v)) && \
272                (Pympfr_AS_MPFR(v)->_mpfr_exp >= context->ctx.emin) && \
273                (Pympfr_AS_MPFR(v)->_mpfr_exp <= context->ctx.emax) \
274            ) \
275        ) \
276    )
277
278
279static PyObject * Pympfr_f2q(PyObject *self, PyObject *args);
280static PyObject * Pygmpy_mpfr(PyObject *self, PyObject *args, PyObject *keywds);
281static PyObject * Pympfr_getprec_attrib(PympfrObject *self, void *closure);
282static PyObject * Pympfr_getrc_attrib(PympfrObject *self, void *closure);
283static PyObject * Pympfr_getimag_attrib(PympfrObject *self, void *closure);
284static PyObject * Pympfr_getreal_attrib(PympfrObject *self, void *closure);
285static int Pympfr_nonzero(PympfrObject *self);
286static PyObject * Pympfr_conjugate(PyObject *self, PyObject *args);
287static PyObject * Pympfr_pos(PympfrObject *self);
288static PyObject * Pympfr_get_emin_min(PyObject *self, PyObject *args);
289static PyObject * Pympfr_get_emax_max(PyObject *self, PyObject *args);
290static PyObject * Pympfr_get_max_precision(PyObject *self, PyObject *args);
291static PyObject * Pympfr_get_exp(PyObject *self, PyObject *other);
292static PyObject * Pympfr_set_exp(PyObject *self, PyObject *args);
293static PyObject * Pympfr_set_sign(PyObject *self, PyObject *args);
294static PyObject * Pympfr_copy_sign(PyObject *self, PyObject *args);
295static PyObject * Pympfr_div_2exp(PyObject *self, PyObject *args);
296static PyObject * Pympfr_mul_2exp(PyObject *self, PyObject *args);
297static PyObject * Pympfr_set_nan(PyObject *self, PyObject *other);
298static PyObject * Pympfr_set_inf(PyObject *self, PyObject *args);
299static PyObject * Pympfr_set_zero(PyObject *self, PyObject *args);
300static PyObject * Pympfr_is_signed(PyObject *self, PyObject *other);
301static PyObject * Pympfr_is_nan(PyObject *self, PyObject *other);
302/* Pympfr_is_number is used to implement is_finite. */
303static PyObject * Pympfr_is_number(PyObject *self, PyObject *other);
304/* Pympfr_is_inf is used to implement is_infinite. */
305static PyObject * Pympfr_is_inf(PyObject *self, PyObject *other);
306static PyObject * Pympfr_is_zero(PyObject *self, PyObject *other);
307static PyObject * Pympfr_is_regular(PyObject *self, PyObject *other);
308static PyObject * Pympfr_is_integer(PyObject *self, PyObject *other);
309static PyObject * Pympfr_digits(PyObject *self, PyObject *args);
310static PyObject * Pympfr_integer_ratio(PyObject *self, PyObject *args);
311static PyObject * Pympfr_mantissa_exp(PyObject *self, PyObject *args);
312static PyObject * Pympfr_simple_fraction(PyObject *self, PyObject *args, PyObject *keywds);
313static Py_hash_t Pympfr_hash(PympfrObject *self);
314static PyObject * Pympfr_pow(PyObject *base, PyObject *exp, PyObject *m);
315static PyObject * Pympfr_const_pi(PyObject *self, PyObject *args, PyObject *keywds);
316static PyObject * Pympfr_const_euler(PyObject *self, PyObject *args, PyObject *keywds);
317static PyObject * Pympfr_const_log2(PyObject *self, PyObject *args, PyObject *keywds);
318static PyObject * Pympfr_const_catalan(PyObject *self, PyObject *args, PyObject *keywds);
319static PyObject * Pympfr_sqrt(PyObject *self, PyObject *other);
320static PyObject * Pympfr_rec_sqrt(PyObject *self, PyObject *other);
321static PyObject * Pympfr_root(PyObject *self, PyObject *args);
322static PyObject * Pympfr_reldiff(PyObject *self, PyObject *args);
323static PyObject * Pympfr_sign(PyObject *self, PyObject *other);
324static PyObject * Pympfr_abs(PympfrObject *x);
325static PyObject * Pympfr_neg(PympfrObject *x);
326static PyObject * Pympfr_ceil(PyObject *self, PyObject *other);
327static PyObject * Pympfr_floor(PyObject *self, PyObject *other);
328static PyObject * Pympfr_trunc(PyObject *self, PyObject *other);
329static PyObject * Pympfr_round2(PyObject *self, PyObject *args);
330static PyObject * Pympfr_round10(PyObject *self, PyObject *args);
331static PyObject * Pympfr_round_away(PyObject* self, PyObject *other);
332static PyObject * Pympfr_rint(PyObject* self, PyObject *other);
333static PyObject * Pympfr_rint_ceil(PyObject* self, PyObject *other);
334static PyObject * Pympfr_rint_floor(PyObject* self, PyObject *other);
335static PyObject * Pympfr_rint_trunc(PyObject* self, PyObject *other);
336static PyObject * Pympfr_frac(PyObject* self, PyObject *other);
337static PyObject * Pympfr_modf(PyObject* self, PyObject *other);
338static PyObject * Pympfr_sqr(PyObject* self, PyObject *other);
339static PyObject * Pympfr_cbrt(PyObject* self, PyObject *other);
340static PyObject * Pympfr_log(PyObject* self, PyObject *other);
341static PyObject * Pympfr_log2(PyObject* self, PyObject *other);
342static PyObject * Pympfr_log10(PyObject* self, PyObject *other);
343static PyObject * Pympfr_exp(PyObject* self, PyObject *other);
344static PyObject * Pympfr_exp2(PyObject* self, PyObject *other);
345static PyObject * Pympfr_exp10(PyObject* self, PyObject *other);
346static PyObject * Pympfr_sin(PyObject* self, PyObject *other);
347static PyObject * Pympfr_cos(PyObject* self, PyObject *other);
348static PyObject * Pympfr_tan(PyObject* self, PyObject *other);
349static PyObject * Pympfr_sec(PyObject* self, PyObject *other);
350static PyObject * Pympfr_csc(PyObject* self, PyObject *other);
351static PyObject * Pympfr_cot(PyObject* self, PyObject *other);
352static PyObject * Pympfr_acos(PyObject* self, PyObject *other);
353static PyObject * Pympfr_asin(PyObject* self, PyObject *other);
354static PyObject * Pympfr_atan(PyObject* self, PyObject *other);
355static PyObject * Pympfr_cosh(PyObject* self, PyObject *other);
356static PyObject * Pympfr_sinh(PyObject* self, PyObject *other);
357static PyObject * Pympfr_tanh(PyObject* self, PyObject *other);
358static PyObject * Pympfr_sech(PyObject* self, PyObject *other);
359static PyObject * Pympfr_csch(PyObject* self, PyObject *other);
360static PyObject * Pympfr_coth(PyObject* self, PyObject *other);
361static PyObject * Pympfr_acosh(PyObject* self, PyObject *other);
362static PyObject * Pympfr_asinh(PyObject* self, PyObject *other);
363static PyObject * Pympfr_atanh(PyObject* self, PyObject *other);
364static PyObject * Pympfr_log1p(PyObject* self, PyObject *other);
365static PyObject * Pympfr_expm1(PyObject* self, PyObject *other);
366static PyObject * Pympfr_eint(PyObject* self, PyObject *other);
367static PyObject * Pympfr_li2(PyObject* self, PyObject *other);
368static PyObject * Pympfr_gamma(PyObject* self, PyObject *other);
369static PyObject * Pympfr_lngamma(PyObject* self, PyObject *other);
370static PyObject * Pympfr_lgamma(PyObject* self, PyObject *other);
371static PyObject * Pympfr_digamma(PyObject* self, PyObject *other);
372static PyObject * Pympfr_zeta(PyObject* self, PyObject *other);
373static PyObject * Pympfr_erf(PyObject* self, PyObject *other);
374static PyObject * Pympfr_erfc(PyObject* self, PyObject *other);
375static PyObject * Pympfr_j0(PyObject* self, PyObject *other);
376static PyObject * Pympfr_j1(PyObject* self, PyObject *other);
377static PyObject * Pympfr_jn(PyObject* self, PyObject *other);
378static PyObject * Pympfr_y0(PyObject* self, PyObject *other);
379static PyObject * Pympfr_y1(PyObject* self, PyObject *other);
380static PyObject * Pympfr_yn(PyObject* self, PyObject *other);
381static PyObject * Pympfr_ai(PyObject* self, PyObject *other);
382static PyObject * Pympfr_add_fast(PyObject *x, PyObject *y);
383static PyObject * Pympfr_add(PyObject* self, PyObject *other);
384static PyObject * Pympfr_sub_fast(PyObject *x, PyObject *y);
385static PyObject * Pympfr_sub(PyObject* self, PyObject *other);
386static PyObject * Pympfr_mul_fast(PyObject *x, PyObject *y);
387static PyObject * Pympfr_mul(PyObject *self, PyObject *args);
388static PyObject * Pympfr_truediv_fast(PyObject *x, PyObject *y);
389#ifdef PY2
390static PyObject * Pympfr_div2_fast(PyObject *x, PyObject *y);
391#endif
392static PyObject * Pympfr_div(PyObject *self, PyObject *args);
393static PyObject * Pympfr_fmod(PyObject *self, PyObject *args);
394static PyObject * Pympfr_remainder(PyObject *self, PyObject *args);
395static PyObject * Pympfr_remquo(PyObject* self, PyObject *args);
396static PyObject * Pympfr_frexp(PyObject *self, PyObject *other);
397static PyObject * Pympfr_atan2(PyObject *self, PyObject *args);
398static PyObject * Pympfr_agm(PyObject *self, PyObject *args);
399static PyObject * Pympfr_hypot(PyObject *self, PyObject *args);
400static PyObject * Pympfr_max2(PyObject *self, PyObject *args);
401static PyObject * Pympfr_min2(PyObject *self, PyObject *args);
402static PyObject * Pympfr_nexttoward(PyObject *self, PyObject *args);
403static PyObject * Pympfr_nextabove(PyObject *self, PyObject *other);
404static PyObject * Pympfr_nextbelow(PyObject *self, PyObject *other);
405static PyObject * Pympfr_sin_cos(PyObject *self, PyObject *other);
406static PyObject * Pympfr_sinh_cosh(PyObject *self, PyObject *other);
407static PyObject * Pympfr_fma(PyObject *self, PyObject *args);
408static PyObject * Pympfr_fms(PyObject *self, PyObject *args);
409static PyObject * Pympfr_factorial(PyObject *self, PyObject *other);
410static PyObject * Pympfr_is_lessgreater(PyObject *self, PyObject *args);
411static PyObject * Pympfr_is_unordered(PyObject *self, PyObject *args);
412static PyObject * Pympfr_check_range(PyObject *self, PyObject *other);
413static PyObject * Pympfr_fsum(PyObject *self, PyObject *other);
414static PyObject * Pympfr_degrees(PyObject *self, PyObject *other);
415static PyObject * Pympfr_radians(PyObject *self, PyObject *other);
416static PyObject * Pympfr_format(PyObject *self, PyObject *args);
417
418#ifdef __cplusplus
419}
420#endif
421#endif