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