gmpy2_minus.c
1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 2 * gmpy2_minus.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 /* This file implements __neg__ and context.minus(). 28 * 29 * Public API 30 * ========== 31 * The following function is available as part of GMPY2's C API. If the value 32 * of context is NULL, then the function should use the currently active 33 * context. 34 * 35 * GMPy_Number_Minus(Number, context) 36 * 37 * Private API 38 * =========== 39 * GMPy_MPZ_Minus_Slot 40 * GMPy_MPQ_Minus_Slot 41 * GMPy_MPFR_Minus_Slot 42 * GMPy_MPC_Minus_Slot 43 * 44 * GMPy_Integer_Minus(Integer, context|NULL) 45 * GMPy_Rational_Minus(Rational, context|NULL) 46 * GMPy_Real_Minus(Real, context|NULL) 47 * GMPy_Complex_Minus(Complex, context|NULL) 48 * 49 * GMPy_Context_Minus(context, args) 50 */ 51 52 static PyObject * 53 _GMPy_MPZ_Minus(PyObject *x, CTXT_Object *context) 54 { 55 MPZ_Object *result; 56 57 if (!(result = GMPy_MPZ_New(context))) { 58 return NULL; 59 } 60 61 mpz_neg(result->z, MPZ(x)); 62 return (PyObject*)result; 63 } 64 static PyObject * 65 GMPy_Integer_Minus(PyObject *x, CTXT_Object *context) 66 { 67 PyObject *result, *tempx; 68 69 if (!(tempx = (PyObject*)GMPy_MPZ_From_Integer(x, context))) { 70 return NULL; 71 } 72 73 result = _GMPy_MPZ_Minus(tempx, context); 74 Py_DECREF(tempx); 75 return result; 76 } 77 78 static PyObject * 79 GMPy_MPZ_Minus_Slot(MPZ_Object *x) 80 { 81 return _GMPy_MPZ_Minus((PyObject*)x, NULL); 82 } 83 84 static PyObject * 85 _GMPy_MPQ_Minus(PyObject *x, CTXT_Object *context) 86 { 87 MPQ_Object *result; 88 89 CHECK_CONTEXT(context); 90 91 if (!(result = GMPy_MPQ_New(context))) { 92 return NULL; 93 } 94 95 mpq_neg(result->q, MPQ(x)); 96 return (PyObject*)result; 97 } 98 99 static PyObject * 100 GMPy_Rational_Minus(PyObject *x, CTXT_Object *context) 101 { 102 PyObject *result, *tempx; 103 104 CHECK_CONTEXT(context); 105 106 if (!(tempx = (PyObject*)GMPy_MPQ_From_Rational(x, context))) { 107 return NULL; 108 } 109 110 result = _GMPy_MPQ_Minus(tempx, context); 111 Py_DECREF(tempx); 112 return result; 113 } 114 115 static PyObject * 116 GMPy_MPQ_Minus_Slot(MPQ_Object *x) 117 { 118 return _GMPy_MPQ_Minus((PyObject*)x, NULL); 119 } 120 121 static PyObject * 122 _GMPy_MPFR_Minus(PyObject *x, CTXT_Object *context) 123 { 124 MPFR_Object *result; 125 126 CHECK_CONTEXT(context); 127 128 if (!(result = GMPy_MPFR_New(0, context))) { 129 return NULL; 130 } 131 132 mpfr_clear_flags(); 133 134 result->rc = mpfr_neg(result->f, MPFR(x), GET_MPFR_ROUND(context)); 135 _GMPy_MPFR_Cleanup(&result, context); 136 return (PyObject*)result; 137 } 138 139 static PyObject * 140 GMPy_Real_Minus(PyObject *x, CTXT_Object *context) 141 { 142 PyObject *result, *tempx; 143 144 CHECK_CONTEXT(context); 145 146 if (!(tempx = (PyObject*)GMPy_MPFR_From_Real(x, 1, context))) { 147 return NULL; 148 } 149 150 result = _GMPy_MPFR_Minus(tempx, context); 151 Py_DECREF(tempx); 152 return result; 153 } 154 155 static PyObject * 156 GMPy_MPFR_Minus_Slot(MPFR_Object *x) 157 { 158 return _GMPy_MPFR_Minus((PyObject*)x, NULL); 159 } 160 161 static PyObject * 162 _GMPy_MPC_Minus(PyObject *x, CTXT_Object *context) 163 { 164 MPC_Object *result; 165 166 CHECK_CONTEXT(context); 167 168 if (!(result = GMPy_MPC_New(0, 0, context))) { 169 return NULL; 170 } 171 172 result->rc = mpc_neg(result->c, MPC(x), GET_MPC_ROUND(context)); 173 _GMPy_MPC_Cleanup(&result, context); 174 return (PyObject*)result; 175 } 176 177 static PyObject * 178 GMPy_Complex_Minus(PyObject *x, CTXT_Object *context) 179 { 180 PyObject *result, *tempx; 181 182 CHECK_CONTEXT(context); 183 184 if (!(tempx = (PyObject*)GMPy_MPC_From_Complex(x, 1, 1, context))) { 185 return NULL; 186 } 187 188 result = _GMPy_MPC_Minus(tempx, context); 189 Py_DECREF(tempx); 190 return result; 191 } 192 193 static PyObject * 194 GMPy_MPC_Minus_Slot(MPC_Object *x) 195 { 196 return _GMPy_MPC_Minus((PyObject*)x, NULL); 197 } 198 199 static PyObject * 200 GMPy_Number_Minus(PyObject *x, CTXT_Object *context) 201 { 202 if (MPZ_Check(x)) 203 return _GMPy_MPZ_Minus(x, context); 204 205 if (MPQ_Check(x)) 206 return _GMPy_MPQ_Minus(x, context); 207 208 if (MPFR_Check(x)) 209 return _GMPy_MPFR_Minus(x, context); 210 211 if (MPC_Check(x)) 212 return _GMPy_MPC_Minus(x, context); 213 214 if (IS_INTEGER(x)) 215 return GMPy_Integer_Minus(x, context); 216 217 if (IS_RATIONAL_ONLY(x)) 218 return GMPy_Rational_Minus(x, context); 219 220 if (IS_REAL_ONLY(x)) 221 return GMPy_Real_Minus(x, context); 222 223 if (IS_COMPLEX_ONLY(x)) 224 return GMPy_Complex_Minus(x, context); 225 226 TYPE_ERROR("minus() argument type not supported"); 227 return NULL; 228 } 229 230 PyDoc_STRVAR(GMPy_doc_context_minus, 231 "context.minus(x) -> number\n\n" 232 "Return -x. The context is applied to the result."); 233 234 static PyObject * 235 GMPy_Context_Minus(PyObject *self, PyObject *args) 236 { 237 CTXT_Object *context = NULL; 238 239 if (PyTuple_GET_SIZE(args) != 1) { 240 TYPE_ERROR("minus() requires 1 argument."); 241 return NULL; 242 } 243 244 if (self && CTXT_Check(self)) { 245 context = (CTXT_Object*)self; 246 } 247 else { 248 CHECK_CONTEXT(context); 249 } 250 251 return GMPy_Number_Minus(PyTuple_GET_ITEM(args, 0), context); 252 } 253