gmpy2_sign.c
1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 2 * gmpy2_sign.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 static PyObject * 28 GMPy_Integer_Sign(PyObject *x, CTXT_Object *context) 29 { 30 long res; 31 MPZ_Object *tempx; 32 33 if (!(tempx = GMPy_MPZ_From_Integer(x, context))) { 34 return NULL; 35 } 36 else { 37 res = mpz_sgn(tempx->z); 38 Py_DECREF((PyObject*)tempx); 39 return PyIntOrLong_FromLong(res); 40 } 41 } 42 43 static PyObject * 44 GMPy_Rational_Sign(PyObject *x, CTXT_Object *context) 45 { 46 long res; 47 MPQ_Object *tempx; 48 49 if (!(tempx = GMPy_MPQ_From_Rational(x, context))) { 50 return NULL; 51 } 52 else { 53 res = mpq_sgn(tempx->q); 54 Py_DECREF((PyObject*)tempx); 55 return PyIntOrLong_FromLong(res); 56 } 57 } 58 59 static PyObject * 60 GMPy_Real_Sign(PyObject *x, CTXT_Object *context) 61 { 62 long sign; 63 MPFR_Object *tempx; 64 PyObject *result; 65 66 CHECK_CONTEXT(context); 67 68 if (!(tempx = GMPy_MPFR_From_Real(x, 1, context))) { 69 return NULL; 70 } 71 else { 72 mpfr_clear_flags(); 73 sign = mpfr_sgn(tempx->f); 74 Py_DECREF((PyObject*)tempx); 75 result = PyIntOrLong_FromLong(sign); 76 GMPY_CHECK_ERANGE(result, context, "sign() of invalid value (NaN)"); 77 return result; 78 } 79 } 80 81 static PyObject * 82 GMPy_Number_Sign(PyObject *x, CTXT_Object *context) 83 { 84 if (IS_INTEGER(x)) 85 return GMPy_Integer_Sign(x, context); 86 else if (IS_RATIONAL_ONLY(x)) 87 return GMPy_Rational_Sign(x, context); 88 else if (IS_REAL_ONLY(x)) 89 return GMPy_Real_Sign(x, context); 90 91 TYPE_ERROR("sign() argument type not supported"); 92 return NULL; 93 } 94 95 PyDoc_STRVAR(GMPy_doc_function_sign, 96 "sign(x) -> number\n\n" 97 "Return -1 if x < 0, 0 if x == 0, or +1 if x >0."); 98 99 static PyObject * 100 GMPy_Context_Sign(PyObject *self, PyObject *other) 101 { 102 CTXT_Object *context = NULL; 103 104 if (self && CTXT_Check(self)) { 105 context = (CTXT_Object*)self; 106 } 107 else { 108 CHECK_CONTEXT(context); 109 } 110 111 return GMPy_Number_Sign(other, context); 112 }