-
Notifications
You must be signed in to change notification settings - Fork 86
/
gmpy2_convert.h
185 lines (155 loc) · 8.16 KB
/
gmpy2_convert.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* gmpy_convert.h *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Python interface to the GMP, MPFR, and MPC multiple precision *
* libraries. *
* *
* Copyright 2000 - 2009 Alex Martelli *
* *
* Copyright 2008 - 2024 Case Van Horsen *
* *
* This file is part of GMPY2. *
* *
* GMPY2 is free software: you can redistribute it and/or modify it under *
* the terms of the GNU Lesser General Public License as published by the *
* Free Software Foundation, either version 3 of the License, or (at your *
* option) any later version. *
* *
* GMPY2 is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public *
* License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public *
* License along with GMPY2; if not, see <http://www.gnu.org/licenses/> *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#ifndef GMPY2_CONVERT_H
#define GMPY2_CONVERT_H
#ifdef __cplusplus
extern "C" {
#endif
/* The following macros classify the numeric types that are supported by
* gmpy2.
*/
#define HAS_MPZ_CONVERSION(x) (PyObject_HasAttrString(x, "__mpz__"))
#define HAS_MPQ_CONVERSION(x) (PyObject_HasAttrString(x, "__mpq__"))
#define HAS_MPFR_CONVERSION(x) (PyObject_HasAttrString(x, "__mpfr__"))
#define HAS_MPC_CONVERSION(x) (PyObject_HasAttrString(x, "__mpc__"))
#define HAS_STRICT_MPZ_CONVERSION(x) (HAS_MPZ_CONVERSION(x) && \
!HAS_MPQ_CONVERSION(x))
#define HAS_STRICT_MPFR_CONVERSION(x) (HAS_MPFR_CONVERSION(x) && \
!HAS_MPC_CONVERSION(x))
#define IS_FRACTION(x) (!strcmp(Py_TYPE(x)->tp_name, "Fraction"))
#define IS_RATIONAL_ONLY(x) (MPQ_Check(x) || IS_FRACTION(x) || \
HAS_MPQ_CONVERSION(x))
#define IS_INTEGER(x) (MPZ_Check(x) || PyLong_Check(x) || \
XMPZ_Check(x) || HAS_STRICT_MPZ_CONVERSION(x))
#define IS_RATIONAL(x) (MPQ_Check(x) || IS_FRACTION(x) || \
MPZ_Check(x) || PyLong_Check(x) || \
XMPZ_Check(x) || HAS_MPQ_CONVERSION(x) || \
HAS_MPZ_CONVERSION(x))
#define IS_DECIMAL(x) (!strcmp(Py_TYPE(x)->tp_name, "decimal.Decimal"))
#define IS_REAL_ONLY(x) (MPFR_Check(x) || PyFloat_Check(x) || \
HAS_STRICT_MPFR_CONVERSION(x) || IS_DECIMAL(x))
#define IS_REAL(x) (IS_RATIONAL(x) || IS_REAL_ONLY(x))
#define IS_COMPLEX_ONLY(x) (MPC_Check(x) || PyComplex_Check(x) || \
HAS_MPC_CONVERSION(x))
#define IS_COMPLEX(x) (IS_REAL(x) || IS_COMPLEX_ONLY(x))
/* Define constants used in gmpy2_convert.c->GMPy_ObjectType. */
#define OBJ_TYPE_UNKNOWN 0
#define OBJ_TYPE_MPZ 1
#define OBJ_TYPE_XMPZ 2
#define OBJ_TYPE_PyInteger 3
#define OBJ_TYPE_HAS_MPZ 4
/* 5 TO 14 reserved for additional integer types. */
#define OBJ_TYPE_INTEGER 15
#define OBJ_TYPE_MPQ 16
#define OBJ_TYPE_PyFraction 17
#define OBJ_TYPE_HAS_MPQ 18
/* 19 to 30 reserved for additional rational types. */
#define OBJ_TYPE_RATIONAL 31
#define OBJ_TYPE_MPFR 32
#define OBJ_TYPE_PyFloat 33
#define OBJ_TYPE_HAS_MPFR 34
/* 35 to 46 reserved for additional real types. */
#define OBJ_TYPE_REAL 47
#define OBJ_TYPE_MPC 48
#define OBJ_TYPE_PyComplex 49
#define OBJ_TYPE_HAS_MPC 50
/* 50 to 62 reserved for additional complex types. */
#define OBJ_TYPE_COMPLEX 63
#define OBJ_TYPE_MAX 64
/* The following macros are the recommended method to check the result of the
* object type check.
*/
#define IS_TYPE_UNKNOWN(x) (!OBJ_TYPE_UNKNOWN)
#define IS_TYPE_MPZ(x) (x == OBJ_TYPE_MPZ)
#define IS_TYPE_XMPZ(x) (x == OBJ_TYPE_XMPZ)
#define IS_TYPE_MPZANY(x) ((x == OBJ_TYPE_MPZ) || \
(x == OBJ_TYPE_XMPZ))
#define IS_TYPE_PyInteger(x) (x == OBJ_TYPE_PyInteger)
#define IS_TYPE_HAS_MPZ(x) (x == OBJ_TYPE_HAS_MPZ)
#define IS_TYPE_INTEGER(x) ((x > OBJ_TYPE_UNKNOWN) && \
(x < OBJ_TYPE_INTEGER))
#define IS_TYPE_MPQ(x) (x == OBJ_TYPE_MPQ)
#define IS_TYPE_PyFraction(x) (x == OBJ_TYPE_PyFraction)
#define IS_TYPE_HAS_MPQ(x) (x == OBJ_TYPE_HAS_MPQ)
#define IS_TYPE_RATIONAL(x) ((x > OBJ_TYPE_UNKNOWN) && \
(x < OBJ_TYPE_RATIONAL))
#define IS_TYPE_RATIONAL_ONLY(x) ((x > OBJ_TYPE_INTEGER) && \
(x < OBJ_TYPE_RATIONAL))
#define IS_TYPE_MPFR(x) (x == OBJ_TYPE_MPFR)
#define IS_TYPE_PyFloat(x) (x == OBJ_TYPE_PyFloat)
#define IS_TYPE_HAS_MPFR(x) (x == OBJ_TYPE_HAS_MPFR)
#define IS_TYPE_REAL(x) ((x > OBJ_TYPE_UNKNOWN) && \
(x < OBJ_TYPE_REAL))
#define IS_TYPE_REAL_ONLY(x) ((x > OBJ_TYPE_RATIONAL) && \
(x < OBJ_TYPE_REAL))
#define IS_TYPE_MPC(x) (x == OBJ_TYPE_MPC)
#define IS_TYPE_PyComplex(x) (x == OBJ_TYPE_PyComplex)
#define IS_TYPE_HAS_MPC(x) (x == OBJ_TYPE_HAS_MPC)
#define IS_TYPE_COMPLEX(x) ((x > OBJ_TYPE_UNKNOWN) && \
(x < OBJ_TYPE_COMPLEX))
#define IS_TYPE_COMPLEX_ONLY(x) ((x > OBJ_TYPE_REAL) && \
(x < OBJ_TYPE_COMPLEX))
/* Compatibility macros (to work with PyLongObject internals).
*/
#if PY_VERSION_HEX >= 0x030C0000
# define TAG_FROM_SIGN_AND_SIZE(is_neg, size) ((is_neg?2:(size==0)) | (((size_t)size) << 3))
# define _PyLong_SetSignAndDigitCount(obj, is_neg, size) (obj->long_value.lv_tag = TAG_FROM_SIGN_AND_SIZE(is_neg, size))
#elif PY_VERSION_HEX >= 0x030900A4
# define _PyLong_SetSignAndDigitCount(obj, is_neg, size) (Py_SET_SIZE(obj, (is_neg?-1:1)*size))
#else
# define _PyLong_SetSignAndDigitCount(obj, is_neg, size) (Py_SIZE(obj) = (is_neg?-1:1)*size)
#endif
#if PY_VERSION_HEX >= 0x030C0000
# define GET_OB_DIGIT(obj) obj->long_value.ob_digit
# define _PyLong_IsNegative(obj) ((obj->long_value.lv_tag & 3) == 2)
# define _PyLong_DigitCount(obj) (obj->long_value.lv_tag >> 3)
#else
# define GET_OB_DIGIT(obj) obj->ob_digit
# define _PyLong_IsNegative(obj) (Py_SIZE(obj) < 0)
# define _PyLong_DigitCount(obj) (_PyLong_IsNegative(obj)? -Py_SIZE(obj):Py_SIZE(obj))
#endif
/* Since the macros are used in gmpy2's codebase, these functions are skipped
* until they are needed for the C API in the future.
*/
#if 0
/* Checks for mpz, xmpz, and the integer types included with Python. */
static int GMPy_isInteger(PyObject *obj);
/* Checks for the Fraction type included with Python. */
static int GMPy_isFraction(PyObject *obj);
/* Combined mpq, isInteger() and isFraction() check. */
static int GMPy_isRational(PyObject *obj);
/* Combined mpfr, PyFloat, and isRational() check. */
static int GMPy_isReal(PyObject *obj);
/* Combined mpc, PyComplex, and isReal() check. */
static int GMPy_isComplex(PyObject *obj);
#endif
/* ======== C helper routines ======== */
static int mpz_set_PyStr(mpz_t z, PyObject *s, int base);
static PyObject * mpz_ascii(mpz_t z, int base, int option, int which);
#ifdef __cplusplus
}
#endif
#endif