1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2 * gmpy2_square.c *
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, 2014, *
11 * 2015, 2016, 2017, 2018, 2019, 2020 Case Van Horsen *
12 * *
13 * This file is part of GMPY2. *
14 * *
15 * GMPY2 is free software: you can redistribute it and/or modify it under *
16 * the terms of the GNU Lesser General Public License as published by the *
17 * Free Software Foundation, either version 3 of the License, or (at your *
18 * option) any later version. *
19 * *
20 * GMPY2 is distributed in the hope that it will be useful, but WITHOUT *
21 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
22 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public *
23 * License for more details. *
24 * *
25 * You should have received a copy of the GNU Lesser General Public *
26 * License along with GMPY2; if not, see <http://www.gnu.org/licenses/> *
27 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
28
29 /* Public API
30 * ==========
31 * The following function is available as part of GMPY2's C API. A NULL value
32 * for context implies the function should use the currently active context.
33 *
34 * GMPy_Number_Square(Number, Number, context|NULL)
35 *
36 * Private API
37 * ===========
38 * GMPy_Integer_Square(Integer, Integer, context|NULL)
39 * GMPy_Rational_Square(Rational, Rational, context|NULL)
40 * GMPy_Real_Square(Real, Real, context|NULL)
41 * GMPy_Complex_Square(Complex, Complex, context|NULL)
42 *
43 * GMPy_Context_Square(context, args)
44 *
45 */
46
47 static PyObject *
_GMPy_MPZ_Square(PyObject * x,CTXT_Object * context)48 _GMPy_MPZ_Square(PyObject *x, CTXT_Object *context)
49 {
50 MPZ_Object *result = NULL;
51
52 if (!(result = GMPy_MPZ_New(context))) {
53 return NULL;
54 }
55
56 mpz_mul(result->z, MPZ(x), MPZ(x));
57 return (PyObject*)result;
58 }
59
60 static PyObject *
GMPy_Integer_Square(PyObject * x,CTXT_Object * context)61 GMPy_Integer_Square(PyObject *x, CTXT_Object *context)
62 {
63 PyObject *result, *tempx;
64
65 if (!(tempx = (PyObject*)GMPy_MPZ_From_Integer(x, context))) {
66 return NULL;
67 }
68
69 result = _GMPy_MPZ_Square(tempx, context);
70 Py_DECREF(tempx);
71 return result;
72 }
73
74 static PyObject *
_GMPy_MPQ_Square(PyObject * x,CTXT_Object * context)75 _GMPy_MPQ_Square(PyObject *x, CTXT_Object *context)
76 {
77 MPQ_Object *result;
78
79 if (!(result = GMPy_MPQ_New(context))) {
80 return NULL;
81 }
82
83 mpq_mul(result->q, MPQ(x), MPQ(x));
84 return (PyObject*)result;
85 }
86
87 static PyObject *
GMPy_Rational_Square(PyObject * x,CTXT_Object * context)88 GMPy_Rational_Square(PyObject *x, CTXT_Object *context)
89 {
90 PyObject *result, *tempx;
91
92 if (!(tempx = (PyObject*)GMPy_MPQ_From_Rational(x, context))) {
93 return NULL;
94 }
95
96 result = _GMPy_MPQ_Square(tempx, context);
97 Py_DECREF(tempx);
98 return result;
99 }
100
101 static PyObject *
_GMPy_MPFR_Square(PyObject * x,CTXT_Object * context)102 _GMPy_MPFR_Square(PyObject *x, CTXT_Object *context)
103 {
104 MPFR_Object *result;
105
106 CHECK_CONTEXT(context);
107
108 if (!(result = GMPy_MPFR_New(0, context))) {
109 return NULL;
110 }
111
112 mpfr_clear_flags();
113
114 mpfr_sqr(result->f, MPFR(x), GET_MPFR_ROUND(context));
115 _GMPy_MPFR_Cleanup(&result, context);
116 return (PyObject*)result;
117 }
118
119 static PyObject *
GMPy_Real_Square(PyObject * x,CTXT_Object * context)120 GMPy_Real_Square(PyObject *x, CTXT_Object *context)
121 {
122 PyObject *result, *tempx;
123
124 CHECK_CONTEXT(context);
125
126 if (!(tempx = (PyObject*)GMPy_MPFR_From_Real(x, 1, context))) {
127 return NULL;
128 }
129
130 result = _GMPy_MPFR_Square(tempx, context);
131 Py_DECREF(tempx);
132 return result;
133 }
134
135 static PyObject *
_GMPy_MPC_Square(PyObject * x,CTXT_Object * context)136 _GMPy_MPC_Square(PyObject *x, CTXT_Object *context)
137 {
138 MPC_Object *result;
139
140 CHECK_CONTEXT(context);
141
142 if (!(result = GMPy_MPC_New(0, 0, context))) {
143 return NULL;
144 }
145
146 mpc_sqr(result->c, MPC(x), GET_MPC_ROUND(context));
147 _GMPy_MPC_Cleanup(&result, context);
148 return (PyObject*)result;
149 }
150 static PyObject *
GMPy_Complex_Square(PyObject * x,CTXT_Object * context)151 GMPy_Complex_Square(PyObject *x, CTXT_Object *context)
152 {
153 PyObject *result, *tempx;
154
155 CHECK_CONTEXT(context);
156
157 if (!(tempx = (PyObject*)GMPy_MPC_From_Complex(x, 1, 1, context))) {
158 return NULL;
159 }
160
161 result = _GMPy_MPC_Square(tempx, context);
162 Py_DECREF(tempx);
163 return result;
164 }
165
166 PyDoc_STRVAR(GMPy_doc_function_square,
167 "square(x) -> number\n\n"
168 "Return x * x. If x is an integer, then the result is an 'mpz'.\n"
169 "If x is a rational, then the result is an 'mpq'. If x is a float,\n"
170 "then the result is an 'mpfr'. If x is a complex number, then the\n"
171 "result is an 'mpc'.");
172
173 PyDoc_STRVAR(GMPy_doc_context_square,
174 "context.square(x) -> number\n\n"
175 "Return x * x. If x is an integer, then the result is an 'mpz'.\n"
176 "If x is a rational, then the result is an 'mpq'. If x is a float,\n"
177 "then the result is an 'mpfr'. If x is a complex number, then the\n"
178 "result is an 'mpc'.");
179
180 static PyObject *
GMPy_Number_Square(PyObject * x,CTXT_Object * context)181 GMPy_Number_Square(PyObject *x, CTXT_Object *context)
182 {
183 if (MPZ_Check(x))
184 return _GMPy_MPZ_Square(x, context);
185
186 if (MPQ_Check(x))
187 return _GMPy_MPQ_Square(x, context);
188
189 if (MPFR_Check(x))
190 return _GMPy_MPFR_Square(x, context);
191
192 if (MPC_Check(x))
193 return _GMPy_MPC_Square(x, context);
194
195 if (IS_INTEGER(x))
196 return GMPy_Integer_Square(x, context);
197
198 if (IS_RATIONAL(x))
199 return GMPy_Rational_Square(x, context);
200
201 if (IS_REAL(x))
202 return GMPy_Real_Square(x, context);
203
204 if (IS_COMPLEX(x))
205 return GMPy_Complex_Square(x, context);
206
207 TYPE_ERROR("square() argument type not supported");
208 return NULL;
209 }
210
211 static PyObject *
GMPy_Context_Square(PyObject * self,PyObject * other)212 GMPy_Context_Square(PyObject *self, PyObject *other)
213 {
214 CTXT_Object *context = NULL;
215
216 if (self && CTXT_Check(self)) {
217 context = (CTXT_Object*)self;
218 }
219 else {
220 CHECK_CONTEXT(context);
221 }
222
223 return GMPy_Number_Square(other, context);
224 }
225
226