/ src / gmpy2_convert_gmp.c
gmpy2_convert_gmp.c
   1  /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
   2   * gmpy2_convert_gmp.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 contains all the conversion functions for GMP data types.
  28   *
  29   * Overview
  30   * --------
  31   * gmpy2 tries to optimize the performance and accuracy of conversions from
  32   * other numeric types. gmpy2 uses a LBYL (Look Before You Leap) approach and
  33   * identifies the numeric type before conversion before conversion to a gmpy2
  34   * type. The basic operations (+, -, *, /) are optimized to directly work with
  35   * some basic types such as C longs or doubles.
  36   */
  37  
  38  /* ======================================================================== *
  39   * Conversion between native Python objects and MPZ.                        *
  40   * ======================================================================== */
  41  
  42  static MPZ_Object *
  43  GMPy_MPZ_From_PyIntOrLong(PyObject *obj, CTXT_Object *context)
  44  {
  45      MPZ_Object *result;
  46      int negative;
  47      Py_ssize_t len;
  48      PyLongObject *templong = (PyLongObject*)obj;
  49  
  50      if(!(result = GMPy_MPZ_New(context))) {
  51          /* LCOV_EXCL_START */
  52          return NULL;
  53          /* LCOV_EXCL_STOP */
  54      }
  55  
  56  #ifdef PY2
  57      if (PyInt_Check(obj)) {
  58          mpz_set_si(result->z, PyInt_AS_LONG(obj));
  59          return result;
  60      }
  61  #endif
  62  
  63      switch (Py_SIZE(templong)) {
  64      case -1:
  65          mpz_set_si(result->z, -(sdigit)templong->ob_digit[0]);
  66          break;
  67      case 0:
  68          mpz_set_si(result->z, 0);
  69          break;
  70      case 1:
  71          mpz_set_si(result->z, templong->ob_digit[0]);
  72          break;
  73      default:
  74          mpz_set_si(result->z, 0);
  75  
  76          if (Py_SIZE(templong) < 0) {
  77              len = - Py_SIZE(templong);
  78              negative = 1;
  79          } else {
  80              len = Py_SIZE(templong);
  81              negative = 0;
  82          }
  83  
  84          mpz_import(result->z, len, -1, sizeof(templong->ob_digit[0]), 0,
  85                     sizeof(templong->ob_digit[0])*8 - PyLong_SHIFT, templong->ob_digit);
  86  
  87          if (negative) {
  88              mpz_neg(result->z, result->z);
  89          }
  90      }
  91      return result;
  92  }
  93  
  94  /* To support creation of temporary mpz objects. */
  95  static void
  96  mpz_set_PyIntOrLong(mpz_t z, PyObject *obj)
  97  {
  98      int negative;
  99      Py_ssize_t len;
 100      PyLongObject *templong = (PyLongObject*)obj;
 101  
 102  #ifdef PY2
 103      if (PyInt_Check(obj)) {
 104          mpz_set_si(z, PyInt_AS_LONG(obj));
 105          return;
 106      }
 107  #endif
 108  
 109      switch (Py_SIZE(templong)) {
 110      case -1:
 111          mpz_set_si(z, -(sdigit)templong->ob_digit[0]);
 112          break;
 113      case 0:
 114          mpz_set_si(z, 0);
 115          break;
 116      case 1:
 117          mpz_set_si(z, templong->ob_digit[0]);
 118          break;
 119      default:
 120          mpz_set_si(z, 0);
 121  
 122          if (Py_SIZE(templong) < 0) {
 123              len = - Py_SIZE(templong);
 124              negative = 1;
 125          } else {
 126              len = Py_SIZE(templong);
 127              negative = 0;
 128          }
 129  
 130          mpz_import(z, len, -1, sizeof(templong->ob_digit[0]), 0,
 131                     sizeof(templong->ob_digit[0])*8 - PyLong_SHIFT, templong->ob_digit);
 132  
 133          if (negative) {
 134              mpz_neg(z, z);
 135          }
 136      }
 137      return;
 138  }
 139  
 140  static MPZ_Object *
 141  GMPy_MPZ_From_PyStr(PyObject *s, int base, CTXT_Object *context)
 142  {
 143      MPZ_Object *result;
 144  
 145      if (!(result = GMPy_MPZ_New(context))) {
 146          /* LCOV_EXCL_START */
 147          return NULL;
 148          /* LCOV_EXCL_STOP */
 149      }
 150  
 151      if (mpz_set_PyStr(result->z, s, base) == -1) {
 152          Py_DECREF((PyObject*)result);
 153          return NULL;
 154      }
 155      return result;
 156  }
 157  
 158  static MPZ_Object *
 159  GMPy_MPZ_From_PyFloat(PyObject *obj, CTXT_Object *context)
 160  {
 161      MPZ_Object *result;
 162  
 163      if ((result = GMPy_MPZ_New(context))) {
 164          double d = PyFloat_AsDouble(obj);
 165  
 166          if (Py_IS_NAN(d)) {
 167              Py_DECREF((PyObject*)result);
 168              VALUE_ERROR("'mpz' does not support NaN");
 169              return NULL;
 170          }
 171          if (Py_IS_INFINITY(d)) {
 172              Py_DECREF((PyObject*)result);
 173              OVERFLOW_ERROR("'mpz' does not support Infinity");
 174              return NULL;
 175          }
 176          mpz_set_d(result->z, d);
 177      }
 178      return result;
 179  }
 180  
 181  static PyObject *
 182  GMPy_PyLong_From_MPZ(MPZ_Object *obj, CTXT_Object *context)
 183  {
 184      int negative;
 185      size_t count, size;
 186      PyLongObject *result;
 187  
 188      /* Assume gmp uses limbs as least as large as the builtin longs do */
 189  
 190      if (mpz_sgn(obj->z) < 0) {
 191          negative = 1;
 192      } else {
 193          negative = 0;
 194      }
 195  
 196      size = (mpz_sizeinbase(obj->z, 2) + PyLong_SHIFT - 1) / PyLong_SHIFT;
 197  
 198      if (!(result = _PyLong_New(size))) {
 199          /* LCOV_EXCL_START */
 200          return NULL;
 201          /* LCOV_EXCL_STOP */
 202      }
 203  
 204      mpz_export(result->ob_digit, &count, -1, sizeof(result->ob_digit[0]), 0,
 205                 sizeof(result->ob_digit[0])*8 - PyLong_SHIFT, obj->z);
 206  
 207      if (count == 0) {
 208          result->ob_digit[0] = 0;
 209      }
 210  
 211      /* long_normalize() is file-static so we must reimplement it */
 212      /* longobjp = long_normalize(longobjp); */
 213      while ((size>0) && (result->ob_digit[size-1] == 0)) {
 214          size--;
 215      }
 216  #if PY_VERSION_HEX >= 0x030900A4
 217      Py_SET_SIZE(result, size);
 218  #else
 219      Py_SIZE(result) = size;
 220  #endif
 221  
 222      if (negative) {
 223  #if PY_VERSION_HEX >= 0x030900A4
 224          Py_SET_SIZE(result, - Py_SIZE(result));
 225  #else
 226          Py_SIZE(result) = - Py_SIZE(result);
 227  #endif
 228      }
 229      return (PyObject*)result;
 230  }
 231  
 232  #ifdef PY2
 233  static PyObject *
 234  GMPy_MPZ_Long_Slot(MPZ_Object *self)
 235  {
 236      return GMPy_PyLong_From_MPZ(self, NULL);
 237  }
 238  #endif
 239  
 240  /* The PyIntOrLong functions should be used when converting a number back
 241   * to a Python value since is automatically returns an "int" or "long" when
 242   * using Python 2.x. The PyLong_From functions (above) should only be used
 243   * when a PyLong is specifically needed for Python 2.x.
 244   */
 245  
 246  static PyObject *
 247  GMPy_PyIntOrLong_From_MPZ(MPZ_Object *obj, CTXT_Object *context)
 248  {
 249  
 250  #ifdef PY2
 251      if (mpz_fits_slong_p(obj->z)) {
 252          /* cast is safe since we know it fits in a signed long */
 253          return PyInt_FromLong((long)mpz_get_si(obj->z));
 254      }
 255  #endif
 256  
 257      return GMPy_PyLong_From_MPZ(obj, context);
 258  }
 259  
 260  static PyObject *
 261  GMPy_MPZ_Int_Slot(MPZ_Object *self)
 262  {
 263      return GMPy_PyIntOrLong_From_MPZ(self, NULL);
 264  }
 265  
 266  static PyObject *
 267  GMPy_PyFloat_From_MPZ(MPZ_Object *obj, CTXT_Object *context)
 268  {
 269      double res;
 270  
 271      res = mpz_get_d(obj->z);
 272  
 273      if (Py_IS_INFINITY(res)) {
 274          OVERFLOW_ERROR("'mpz' too large to convert to float");
 275          return NULL;
 276      }
 277  
 278      return PyFloat_FromDouble(res);
 279  }
 280  
 281  static PyObject *
 282  GMPy_MPZ_Float_Slot(MPZ_Object *self)
 283  {
 284      return GMPy_PyFloat_From_MPZ(self, NULL);
 285  }
 286  
 287  static PyObject *
 288  GMPy_PyStr_From_MPZ(MPZ_Object *obj, int base, int option, CTXT_Object *context)
 289  {
 290      return mpz_ascii(obj->z, base, option, 0);
 291  }
 292  
 293  static MPZ_Object *
 294  GMPy_MPZ_From_Integer(PyObject *obj, CTXT_Object *context)
 295  {
 296      MPZ_Object *result = NULL;
 297  
 298      if (MPZ_Check(obj)) {
 299          Py_INCREF(obj);
 300          return (MPZ_Object*)obj;
 301      }
 302  
 303      if (PyIntOrLong_Check(obj))
 304          return GMPy_MPZ_From_PyIntOrLong(obj, context);
 305  
 306      if (XMPZ_Check(obj))
 307          return GMPy_MPZ_From_XMPZ((XMPZ_Object*)obj, context);
 308  
 309      if (HAS_STRICT_MPZ_CONVERSION(obj)) {
 310          result = (MPZ_Object *) PyObject_CallMethod(obj, "__mpz__", NULL);
 311  
 312          if (result != NULL && MPZ_Check(result)) {
 313              return result;
 314          }
 315          else {
 316              Py_XDECREF((PyObject*)result);
 317              goto error;
 318          }
 319      }
 320  
 321    error:
 322      TYPE_ERROR("cannot convert object to mpz");
 323      return NULL;
 324  }
 325  
 326  static MPZ_Object *
 327  GMPy_MPZ_From_IntegerWithType(PyObject *obj, int xtype, CTXT_Object *context)
 328  {
 329      MPZ_Object *result = NULL;
 330  
 331      if (IS_TYPE_MPZ(xtype)) {
 332          Py_INCREF(obj);
 333          return (MPZ_Object*)obj;
 334      }
 335  
 336      if (IS_TYPE_PyInteger(xtype))
 337          return GMPy_MPZ_From_PyIntOrLong(obj, context);
 338  
 339      if (IS_TYPE_XMPZ(xtype))
 340          return GMPy_MPZ_From_XMPZ((XMPZ_Object*)obj, context);
 341  
 342      if (IS_TYPE_HAS_MPZ(xtype)) {
 343          result = (MPZ_Object *) PyObject_CallMethod(obj, "__mpz__", NULL);
 344  
 345          if (result != NULL && MPZ_Check(result)) {
 346              return result;
 347          }
 348          else {
 349              Py_XDECREF((PyObject*)result);
 350              goto error;
 351          }
 352      }
 353  
 354    error:
 355      TYPE_ERROR("cannot convert object to mpz");
 356      return NULL;
 357  }
 358  
 359  static MPZ_Object *
 360  GMPy_MPZ_From_IntegerWithTypeAndCopy(PyObject *obj, int xtype, CTXT_Object *context)
 361  {
 362      MPZ_Object *result = NULL, *temp = NULL;
 363  
 364      result = GMPy_MPZ_From_IntegerWithType(obj, xtype, context);
 365  
 366      if (result == NULL)
 367          return result;
 368  
 369      if (Py_REFCNT(result) == 1)
 370          return result;
 371  
 372      if (!(temp = GMPy_MPZ_New(context))) {
 373          /* LCOV_EXCL_START */
 374          return NULL;
 375          /* LCOV_EXCL_STOP */
 376      }
 377  
 378      mpz_set(temp->z, result->z);
 379      Py_DECREF((PyObject*)result);
 380      return temp;
 381  }
 382  
 383  /* str and repr implementations for mpz */
 384  static PyObject *
 385  GMPy_MPZ_Str_Slot(MPZ_Object *self)
 386  {
 387      /* base-10, no tag */
 388      return GMPy_PyStr_From_MPZ(self, 10, 0, NULL);
 389  }
 390  
 391  static PyObject *
 392  GMPy_MPZ_Repr_Slot(MPZ_Object *self)
 393  {
 394      /* base-10, with tag */
 395      return GMPy_PyStr_From_MPZ(self, 10, 1, NULL);
 396  }
 397  
 398  #ifdef SHARED
 399  /* Helper function for argument parsing. Not used in static build. */
 400  
 401  static int
 402  GMPy_MPZ_ConvertArg(PyObject *arg, PyObject **ptr)
 403  {
 404      MPZ_Object *result = GMPy_MPZ_From_IntegerWithType(arg, GMPy_ObjectType(arg), NULL);
 405  
 406      if (result) {
 407          *ptr = (PyObject*)result;
 408          return 1;
 409      }
 410      else {
 411          TYPE_ERROR("argument can not be converted to 'mpz'");
 412          return 0;
 413      }
 414  }
 415  #endif
 416  
 417  /* ======================================================================== *
 418   * Conversion between native Python objects/MPZ and XMPZ.                   *
 419   * ======================================================================== */
 420  
 421  static XMPZ_Object *
 422  GMPy_XMPZ_From_PyIntOrLong(PyObject *obj, CTXT_Object *context)
 423  {
 424      XMPZ_Object *result;
 425      int negative;
 426      Py_ssize_t len;
 427      PyLongObject *templong = (PyLongObject*)obj;
 428  
 429      if(!(result = GMPy_XMPZ_New(context))) {
 430          /* LCOV_EXCL_START */
 431          return NULL;
 432          /* LCOV_EXCL_STOP */
 433      }
 434  
 435  #ifdef PY2
 436      if (PyInt_Check(obj)) {
 437          mpz_set_si(result->z, PyInt_AS_LONG(obj));
 438          return result;
 439      }
 440  #endif
 441  
 442      switch (Py_SIZE(templong)) {
 443      case -1:
 444          mpz_set_si(result->z, -(sdigit)templong->ob_digit[0]);
 445          break;
 446      case 0:
 447          mpz_set_si(result->z, 0);
 448          break;
 449      case 1:
 450          mpz_set_si(result->z, templong->ob_digit[0]);
 451          break;
 452      default:
 453          mpz_set_si(result->z, 0);
 454  
 455          if (Py_SIZE(templong) < 0) {
 456              len = - Py_SIZE(templong);
 457              negative = 1;
 458          } else {
 459              len = Py_SIZE(templong);
 460              negative = 0;
 461          }
 462  
 463          mpz_import(result->z, len, -1, sizeof(templong->ob_digit[0]), 0,
 464                     sizeof(templong->ob_digit[0])*8 - PyLong_SHIFT, templong->ob_digit);
 465  
 466          if (negative) {
 467              mpz_neg(result->z, result->z);
 468          }
 469      }
 470      return result;
 471  }
 472  
 473  static XMPZ_Object *
 474  GMPy_XMPZ_From_PyStr(PyObject *s, int base, CTXT_Object *context)
 475  {
 476      XMPZ_Object *result;
 477  
 478      if (!(result = GMPy_XMPZ_New(context)))
 479          return NULL;
 480  
 481      if (mpz_set_PyStr(result->z, s, base) == -1) {
 482          Py_DECREF((PyObject*)result);
 483          return NULL;
 484      }
 485      return result;
 486  }
 487  
 488  static XMPZ_Object *
 489  GMPy_XMPZ_From_PyFloat(PyObject *obj, CTXT_Object *context)
 490  {
 491      XMPZ_Object *result;
 492  
 493      if ((result = GMPy_XMPZ_New(context))) {
 494          double d = PyFloat_AsDouble(obj);
 495  
 496          if (Py_IS_NAN(d)) {
 497              Py_DECREF((PyObject*)result);
 498              VALUE_ERROR("'xmpz' does not support NaN");
 499              return NULL;
 500          }
 501          if (Py_IS_INFINITY(d)) {
 502              Py_DECREF((PyObject*)result);
 503              OVERFLOW_ERROR("'xmpz' does not support Infinity");
 504              return NULL;
 505          }
 506          mpz_set_d(result->z, d);
 507      }
 508      return result;
 509  }
 510  
 511  static XMPZ_Object *
 512  GMPy_XMPZ_From_MPZ(MPZ_Object *obj, CTXT_Object *context)
 513  {
 514      XMPZ_Object *result;
 515  
 516      if ((result = GMPy_XMPZ_New(context)))
 517          mpz_set(result->z, obj->z);
 518  
 519      return result;
 520  }
 521  
 522  static XMPZ_Object *
 523  GMPy_XMPZ_From_XMPZ(XMPZ_Object *obj, CTXT_Object *context)
 524  {
 525      XMPZ_Object *result;
 526  
 527      if ((result = GMPy_XMPZ_New(context)))
 528          mpz_set(result->z, obj->z);
 529  
 530      return result;
 531  }
 532  
 533  static PyObject *
 534  GMPy_PyStr_From_XMPZ(XMPZ_Object *obj, int base, int option, CTXT_Object *context)
 535  {
 536      return mpz_ascii(obj->z, base, option, 1);
 537  }
 538  
 539  static MPZ_Object *
 540  GMPy_MPZ_From_XMPZ(XMPZ_Object *obj, CTXT_Object *context)
 541  {
 542      MPZ_Object *result;
 543  
 544      if ((result = GMPy_MPZ_New(context)))
 545          mpz_set(result->z, obj->z);
 546  
 547      return result;
 548  }
 549  
 550  /* str and repr implementations for xmpz */
 551  static PyObject *
 552  GMPy_XMPZ_Str_Slot(XMPZ_Object *self)
 553  {
 554      /* base-10, no tag */
 555      return GMPy_PyStr_From_XMPZ(self, 10, 0, NULL);
 556  }
 557  
 558  static PyObject *
 559  GMPy_XMPZ_Repr_Slot(XMPZ_Object *self)
 560  {
 561      /* base-10, with tag */
 562      return GMPy_PyStr_From_XMPZ(self, 10, 1, NULL);
 563  }
 564  
 565  /* ======================================================================== *
 566   * Conversion between native Python objects/MPZ/XMPZ and MPQ.               *
 567   * ======================================================================== */
 568  
 569  static MPQ_Object *
 570  GMPy_MPQ_From_PyIntOrLong(PyObject *obj, CTXT_Object *context)
 571  {
 572      MPQ_Object *result;
 573      MPZ_Object *temp;
 574  
 575      temp = GMPy_MPZ_From_PyIntOrLong(obj, context);
 576  
 577      if (!temp)
 578          return NULL;
 579  
 580      if ((result = GMPy_MPQ_New(context))) {
 581          mpq_set_z(result->q, temp->z);
 582          Py_DECREF((PyObject*)temp);
 583      }
 584      return result;
 585  }
 586  
 587  static MPQ_Object *
 588  GMPy_MPQ_From_PyStr(PyObject *s, int base, CTXT_Object *context)
 589  {
 590      MPQ_Object *result;
 591      char *cp;
 592      char exp_char = 'E';
 593      Py_ssize_t len, i;
 594      PyObject *ascii_str = NULL;
 595      long expt = 0;
 596  
 597      if (!(result = GMPy_MPQ_New(context))) {
 598          /* LCOV_EXCL_START */
 599          return NULL;
 600          /* LCOV_EXCL_STOP */
 601      }
 602  
 603      if (PyBytes_Check(s)) {
 604          len = PyBytes_Size(s);
 605          cp = PyBytes_AsString(s);
 606      }
 607      else if (PyUnicode_Check(s)) {
 608          ascii_str = PyUnicode_AsASCIIString(s);
 609          if (!ascii_str) {
 610              VALUE_ERROR("string contains non-ASCII characters");
 611              goto error;
 612          }
 613          len = PyBytes_Size(ascii_str);
 614          cp = PyBytes_AsString(ascii_str);
 615      }
 616      else {
 617          TYPE_ERROR("object is not string or Unicode");
 618          goto error;
 619      }
 620  
 621      /* Don't allow NULL characters */
 622      for (i = 0; i < len; i++) {
 623          if (cp[i] == '\0') {
 624              VALUE_ERROR("string contains NULL characters");
 625              goto error;
 626          }
 627      }
 628  
 629      {
 630          char *whereslash = strchr((char*)cp, '/');
 631          char *wheredot = strchr((char*)cp, '.');
 632          char *whereexp = strchr((char*)cp, 'E');
 633  
 634          if (!whereexp) {
 635              whereexp = strchr((char*)cp, 'e');
 636              exp_char = 'e';
 637          }
 638  
 639          if (whereslash && wheredot) {
 640              VALUE_ERROR("illegal string: both . and / found");
 641              goto error;
 642          }
 643  
 644          if (wheredot && (base != 10)) {
 645              VALUE_ERROR("illegal string: embedded . requires base=10");
 646              goto error;
 647          }
 648  
 649          /* If base=10, no slash is found, and an exponent symbol is found, then
 650           * assume we have decimal number in scientific format.
 651           */
 652          if (whereexp && !whereslash && (base == 10)) {
 653              /* Temporarily shorten the string and continue processing as
 654               * normal. We'll deal with the exponent later.
 655               */
 656              *whereexp = '\0';
 657              expt = atol(whereexp+1);
 658          }
 659  
 660          /* Handle the case where an embedded decimal point exists. An optional
 661           * exponent is also allowed. We take advantage of the fact that
 662           * mpz_set_str() ignores embedded space characters. We count the
 663           * number of digits after the decimal point and then replace the '.'
 664           * with a ' '. We've already inserted a NUL byte to terminate the
 665           * string in the case when an exponent was entered. The value for
 666           * the exponent has already been read.
 667           */
 668  
 669          if (wheredot) {
 670              char *counter;
 671              long digits = 0;
 672  
 673              counter = wheredot;
 674              digits = 0;
 675              *wheredot = ' ';
 676              while (*++counter != '\0') {
 677                  if (isdigit(*counter))
 678                      digits++;
 679              }
 680              if (-1 == mpz_set_str(mpq_numref(result->q), (char*)cp, base)) {
 681                  if (wheredot)
 682                      *wheredot = '.';
 683                  /* Restore the exponent! */
 684                  if (whereexp && !whereslash && (base == 10))
 685                      *whereexp = exp_char;
 686                  VALUE_ERROR("invalid digits");
 687                  goto error;
 688              }
 689              /* Process the exponent. */
 690              digits = expt - digits;
 691              if (digits < 0) {
 692                  mpz_ui_pow_ui(mpq_denref(result->q), 10, (unsigned long)(-digits));
 693              }
 694              else {
 695                  /* Use the denominator instead of a temporary variable. */
 696                  mpz_ui_pow_ui(mpq_denref(result->q), 10, (unsigned long)(digits));
 697                  mpz_mul(mpq_numref(result->q), mpq_numref(result->q), mpq_denref(result->q));
 698                  mpz_set_ui(mpq_denref(result->q), 1);
 699              }
 700              mpq_canonicalize(result->q);
 701  
 702              /* Restore the decimal point. */
 703              *wheredot = '.';
 704  
 705              /* Restore the exponent! */
 706              if (whereexp && (base == 10))
 707                  *whereexp = exp_char;
 708  
 709              goto finish;
 710          }
 711  
 712          if (whereslash)
 713              *whereslash = '\0';
 714  
 715          /* Read the numerator. */
 716          if (-1 == mpz_set_str(mpq_numref(result->q), (char*)cp, base)) {
 717              if (whereslash)
 718                  *whereslash = '/';
 719              VALUE_ERROR("invalid digits");
 720              goto error;
 721          }
 722  
 723          /* If a slash was present, read the denominator. */
 724          if (whereslash) {
 725              *whereslash = '/';
 726              if (-1 == mpz_set_str(mpq_denref(result->q), whereslash+1, base)) {
 727                  VALUE_ERROR("invalid digits");
 728                  goto error;
 729              }
 730              if (0 == mpz_sgn(mpq_denref(result->q))) {
 731                  ZERO_ERROR("zero denominator in mpq()");
 732                  goto error;
 733              }
 734              mpq_canonicalize(result->q);
 735          }
 736          else {
 737              /* Since no slash was present, either the denominator is 1 or a
 738               * power of 10.
 739               */
 740  
 741              if (expt <= 0) {
 742                  mpz_ui_pow_ui(mpq_denref(result->q), 10, (unsigned long)(-expt));
 743              }
 744              else {
 745                  mpz_ui_pow_ui(mpq_denref(result->q), 10, (unsigned long)(expt));
 746                  mpz_mul(mpq_numref(result->q), mpq_numref(result->q), mpq_denref(result->q));
 747                  mpz_set_ui(mpq_denref(result->q), 1);
 748              }
 749              mpq_canonicalize(result->q);
 750              if (whereexp && (base == 10))
 751                  *whereexp = exp_char;
 752          }
 753      }
 754  
 755    finish:
 756      Py_XDECREF(ascii_str);
 757      return result;
 758  
 759    error:
 760      Py_DECREF((PyObject*)result);
 761      Py_XDECREF(ascii_str);
 762      return NULL;
 763  }
 764  
 765  static MPQ_Object *
 766  GMPy_MPQ_From_PyFloat(PyObject *obj, CTXT_Object *context)
 767  {
 768      MPQ_Object *result;
 769  
 770      if ((result = GMPy_MPQ_New(context))) {
 771          double d = PyFloat_AsDouble(obj);
 772  
 773          if (Py_IS_NAN(d)) {
 774              Py_DECREF((PyObject*)result);
 775              VALUE_ERROR("'mpq' does not support NaN");
 776              return NULL;
 777          }
 778          if (Py_IS_INFINITY(d)) {
 779              Py_DECREF((PyObject*)result);
 780              OVERFLOW_ERROR("'mpq' does not support Infinity");
 781              return NULL;
 782          }
 783          mpq_set_d(result->q, d);
 784      }
 785  
 786      return result;
 787  }
 788  
 789  static MPQ_Object *
 790  GMPy_MPQ_From_MPZ(MPZ_Object *obj, CTXT_Object *context)
 791  {
 792      MPQ_Object *result;
 793  
 794      if ((result = GMPy_MPQ_New(context)))
 795          mpq_set_z(result->q, obj->z);
 796  
 797      return result;
 798  }
 799  
 800  static MPQ_Object *
 801  GMPy_MPQ_From_XMPZ(XMPZ_Object *obj, CTXT_Object *context)
 802  {
 803      MPQ_Object *result;
 804  
 805      if ((result = GMPy_MPQ_New(context)))
 806          mpq_set_z(result->q, obj->z);
 807  
 808      return result;
 809  }
 810  
 811  static MPZ_Object *
 812  GMPy_MPZ_From_MPQ(MPQ_Object *obj, CTXT_Object *context)
 813  {
 814      MPZ_Object *result;
 815  
 816      if ((result = GMPy_MPZ_New(context)))
 817          mpz_set_q(result->z, obj->q);
 818  
 819      return result;
 820  }
 821  
 822  static XMPZ_Object *
 823  GMPy_XMPZ_From_MPQ(MPQ_Object *obj, CTXT_Object *context)
 824  {
 825      XMPZ_Object *result;
 826  
 827      if ((result = GMPy_XMPZ_New(context)))
 828          mpz_set_q(result->z, obj->q);
 829  
 830      return result;
 831  }
 832  #ifdef PY2
 833  static PyObject *
 834  GMPy_PyLong_From_MPQ(MPQ_Object *obj, CTXT_Object *context)
 835  {
 836      PyObject *result;
 837      MPZ_Object *temp;
 838  
 839      temp = GMPy_MPZ_From_MPQ(obj, context);
 840  
 841      if (!temp) {
 842          /* LCOV_EXCL_START */
 843          return NULL;
 844          /* LCOV_EXCL_STOP */
 845      }
 846  
 847      result = GMPy_PyLong_From_MPZ(temp, context);
 848      Py_DECREF((PyObject*)temp);
 849  
 850      return result;
 851  }
 852  
 853  static PyObject *
 854  GMPy_MPQ_Long_Slot(MPQ_Object *self)
 855  {
 856      return GMPy_PyLong_From_MPQ(self, NULL);
 857  }
 858  #endif
 859  
 860  static PyObject *
 861  GMPy_PyIntOrLong_From_MPQ(MPQ_Object *obj, CTXT_Object *context)
 862  {
 863      PyObject *result;
 864      MPZ_Object *temp;
 865  
 866      temp = GMPy_MPZ_From_MPQ(obj, context);
 867  
 868      if (!temp) {
 869          /* LCOV_EXCL_START */
 870          return NULL;
 871          /* LCOV_EXCL_STOP */
 872      }
 873  
 874      result = GMPy_PyIntOrLong_From_MPZ(temp, context);
 875      Py_DECREF((PyObject*)temp);
 876  
 877      return result;
 878  }
 879  
 880  static PyObject *
 881  GMPy_MPQ_Int_Slot(MPQ_Object *self)
 882  {
 883      return GMPy_PyIntOrLong_From_MPQ(self, NULL);
 884  }
 885  
 886  static char* _qtag = "mpq(";
 887  
 888  static PyObject *
 889  GMPy_PyStr_From_MPQ(MPQ_Object *obj, int base, int option, CTXT_Object *context)
 890  {
 891      PyObject *result = NULL, *numstr = NULL, *denstr = NULL;
 892      char buffer[50], *p;
 893  
 894      numstr = mpz_ascii(mpq_numref(obj->q), base, 0, 0);
 895      if (!numstr) {
 896          /* LCOV_EXCL_START */
 897          return NULL;
 898          /* LCOV_EXCL_STOP */
 899      }
 900  
 901      /* Check if denominator is 1 and no tag is requested. If so, just
 902       * return the numerator.
 903       */
 904      if (!(option & 1) && (0 == mpz_cmp_ui(mpq_denref(obj->q),1)))
 905          return numstr;
 906  
 907      denstr = mpz_ascii(mpq_denref(obj->q), base, 0, 0);
 908      if (!denstr) {
 909          /* LCOV_EXCL_START */
 910          Py_DECREF(numstr);
 911          return NULL;
 912          /* LCOV_EXCL_STOP */
 913      }
 914  
 915      /* Build the format string. */
 916      p = buffer;
 917      if (option & 1) {
 918          strcpy(p, _qtag);
 919          p += strlen(p);
 920      }
 921  
 922  #ifdef PY2
 923      *(p++) = '%';
 924      *(p++) = 's';
 925      if (option & 1)
 926          *(p++) = ',';
 927      else
 928          *(p++) = '/';
 929      *(p++) = '%';
 930      *(p++) = 's';
 931      if (option & 1)
 932          *(p++) = ')';
 933      *(p++) = '\00';
 934      result = PyString_FromFormat(buffer, PyString_AS_STRING(numstr),
 935                                   PyString_AS_STRING(denstr));
 936  #else
 937      *(p++) = '%';
 938      *(p++) = 'U';
 939      if (option & 1)
 940          *(p++) = ',';
 941      else
 942          *(p++) = '/';
 943      *(p++) = '%';
 944      *(p++) = 'U';
 945      if (option & 1)
 946          *(p++) = ')';
 947      *(p++) = '\00';
 948      result = PyUnicode_FromFormat(buffer, numstr, denstr);
 949  #endif
 950      Py_DECREF(numstr);
 951      Py_DECREF(denstr);
 952      return result;
 953  }
 954  
 955  static PyObject *
 956  GMPy_PyFloat_From_MPQ(MPQ_Object *obj, CTXT_Object *context)
 957  {
 958      double res;
 959  
 960      res = mpq_get_d(obj->q);
 961  
 962      if (Py_IS_INFINITY(res)) {
 963          OVERFLOW_ERROR("'mpq' too large to convert to float");
 964          return NULL;
 965      }
 966  
 967      return PyFloat_FromDouble(res);
 968  }
 969  
 970  static PyObject *
 971  GMPy_MPQ_Float_Slot(MPQ_Object *self)
 972  {
 973      return GMPy_PyFloat_From_MPQ(self, NULL);
 974  }
 975  
 976  static MPQ_Object*
 977  GMPy_MPQ_From_Fraction(PyObject* obj, CTXT_Object *context)
 978  {
 979      MPQ_Object *result;
 980      PyObject *num, *den;
 981  
 982      if (!(result = GMPy_MPQ_New(context))) {
 983          /* LCOV_EXCL_START */
 984          return NULL;
 985          /* LCOV_EXCL_STOP */
 986      }
 987      mpq_set_si(result->q, 0, 1);
 988  
 989      num = PyObject_GetAttrString(obj, "numerator");
 990      den = PyObject_GetAttrString(obj, "denominator");
 991      if (!num || !PyIntOrLong_Check(num) || !den || !PyIntOrLong_Check(den)) {
 992          SYSTEM_ERROR("Object does not appear to be Fraction");
 993          Py_XDECREF(num);
 994          Py_XDECREF(den);
 995          Py_DECREF((PyObject*)result);
 996          return NULL;
 997      }
 998      mpz_set_PyIntOrLong(mpq_numref(result->q), num);
 999      mpz_set_PyIntOrLong(mpq_denref(result->q), den);
1000      Py_DECREF(num);
1001      Py_DECREF(den);
1002      return result;
1003  }
1004  
1005  static MPQ_Object*
1006  GMPy_MPQ_From_Number(PyObject *obj, CTXT_Object *context)
1007  {
1008      if (MPQ_Check(obj)) {
1009          Py_INCREF(obj);
1010          return (MPQ_Object*)obj;
1011      }
1012  
1013      if (MPZ_Check(obj))
1014          return GMPy_MPQ_From_MPZ((MPZ_Object*)obj, context);
1015  
1016      if (MPFR_Check(obj))
1017          return GMPy_MPQ_From_MPFR((MPFR_Object*)obj, context);
1018  
1019      if (PyFloat_Check(obj))
1020          return GMPy_MPQ_From_PyFloat(obj, context);
1021  
1022      if (PyIntOrLong_Check(obj))
1023          return GMPy_MPQ_From_PyIntOrLong(obj, context);
1024  
1025      if (XMPZ_Check(obj))
1026          return GMPy_MPQ_From_XMPZ((XMPZ_Object*)obj, context);
1027  
1028      if (IS_FRACTION(obj))
1029          return GMPy_MPQ_From_Fraction(obj, context);
1030  
1031      if (HAS_MPQ_CONVERSION(obj)) {
1032          MPQ_Object * res = (MPQ_Object *) PyObject_CallMethod(obj, "__mpq__", NULL);
1033  
1034          if (res != NULL && MPQ_Check(res)) {
1035              return res;
1036          }
1037          else {
1038              Py_XDECREF((PyObject*)res);
1039              goto error;
1040          }
1041      }
1042  
1043      if (HAS_MPZ_CONVERSION(obj)) {
1044          MPZ_Object * res = (MPZ_Object *) PyObject_CallMethod(obj, "__mpz__", NULL);
1045  
1046          if (res != NULL && MPZ_Check(res)) {
1047              MPQ_Object * temp = GMPy_MPQ_From_MPZ(res, context);
1048              Py_DECREF(res);
1049              return temp;
1050          }
1051          else {
1052              Py_XDECREF((PyObject*)res);
1053              goto error;
1054          }
1055      }
1056  
1057    error:
1058      TYPE_ERROR("cannot convert object to mpq");
1059      return NULL;
1060  }
1061  
1062  static MPQ_Object*
1063  GMPy_MPQ_From_NumberWithType(PyObject *obj, int xtype, CTXT_Object *context)
1064  {
1065      if (IS_TYPE_MPQ(xtype)) {
1066          Py_INCREF(obj);
1067          return (MPQ_Object*)obj;
1068      }
1069  
1070      if (IS_TYPE_MPZ(xtype))
1071          return GMPy_MPQ_From_MPZ((MPZ_Object*)obj, context);
1072  
1073      if (IS_TYPE_MPFR(xtype))
1074          return GMPy_MPQ_From_MPFR((MPFR_Object*)obj, context);
1075  
1076      if (IS_TYPE_PyFloat(xtype))
1077          return GMPy_MPQ_From_PyFloat(obj, context);
1078  
1079      if (IS_TYPE_PyInteger(xtype))
1080          return GMPy_MPQ_From_PyIntOrLong(obj, context);
1081  
1082      if (IS_TYPE_XMPZ(xtype))
1083          return GMPy_MPQ_From_XMPZ((XMPZ_Object*)obj, context);
1084  
1085      if (IS_TYPE_PyFraction(xtype))
1086          return GMPy_MPQ_From_Fraction(obj, context);
1087  
1088      if (IS_TYPE_HAS_MPQ(xtype)) {
1089          MPQ_Object * res = (MPQ_Object *) PyObject_CallMethod(obj, "__mpq__", NULL);
1090  
1091          if (res != NULL && MPQ_Check(res)) {
1092              return res;
1093          }
1094          else {
1095              Py_XDECREF((PyObject*)res);
1096              goto error;
1097          }
1098      }
1099  
1100      if (IS_TYPE_HAS_MPZ(xtype)) {
1101          MPZ_Object * res = (MPZ_Object *) PyObject_CallMethod(obj, "__mpz__", NULL);
1102  
1103          if (res != NULL && MPZ_Check(res)) {
1104              MPQ_Object * temp = GMPy_MPQ_From_MPZ(res, context);
1105              Py_DECREF(res);
1106              return temp;
1107          }
1108          else {
1109              Py_XDECREF((PyObject*)res);
1110              goto error;
1111          }
1112      }
1113  
1114    error:
1115      TYPE_ERROR("cannot convert object to mpq");
1116      return NULL;
1117  }
1118  
1119  static MPQ_Object*
1120  GMPy_MPQ_From_RationalWithTypeAndCopy(PyObject *obj, int xtype, CTXT_Object *context)
1121  {
1122      MPQ_Object *result = NULL, *temp = NULL;
1123  
1124      result = GMPy_MPQ_From_RationalWithType(obj, xtype, context);
1125  
1126      if (result == NULL)
1127          return result;
1128  
1129      if (Py_REFCNT(result) == 1)
1130          return result;
1131  
1132      if (!(temp = GMPy_MPQ_New(context))) {
1133          /* LCOV_EXCL_START */
1134          return NULL;
1135          /* LCOV_EXCL_STOP */
1136      }
1137  
1138      mpq_set(temp->q, result->q);
1139      Py_DECREF((PyObject*)result);
1140      return temp;
1141  }
1142  
1143  static MPQ_Object*
1144  GMPy_MPQ_From_Rational(PyObject *obj, CTXT_Object *context)
1145  {
1146      if (MPQ_Check(obj)) {
1147          Py_INCREF(obj);
1148          return (MPQ_Object*)obj;
1149      }
1150  
1151      if (MPZ_Check(obj))
1152          return GMPy_MPQ_From_MPZ((MPZ_Object*)obj, context);
1153  
1154      if (PyIntOrLong_Check(obj))
1155          return GMPy_MPQ_From_PyIntOrLong(obj, context);
1156  
1157      if (XMPZ_Check(obj))
1158          return GMPy_MPQ_From_XMPZ((XMPZ_Object*)obj, context);
1159  
1160      if (IS_FRACTION(obj))
1161          return GMPy_MPQ_From_Fraction(obj, context);
1162  
1163      if (HAS_MPQ_CONVERSION(obj)) {
1164          MPQ_Object * res = (MPQ_Object *) PyObject_CallMethod(obj, "__mpq__", NULL);
1165  
1166          if (res != NULL && MPQ_Check(res)) {
1167              return res;
1168          }
1169          else {
1170              Py_XDECREF((PyObject*)res);
1171              goto error;
1172          }
1173      }
1174  
1175      if (HAS_MPZ_CONVERSION(obj)) {
1176          MPZ_Object * res = (MPZ_Object *) PyObject_CallMethod(obj, "__mpz__", NULL);
1177  
1178          if (res != NULL && MPZ_Check(res)) {
1179              MPQ_Object * temp = GMPy_MPQ_From_MPZ(res, context);
1180              Py_DECREF(res);
1181              return temp;
1182          }
1183          else {
1184              Py_XDECREF((PyObject*)res);
1185              goto error;
1186          }
1187      }
1188  
1189    error:
1190      TYPE_ERROR("cannot convert object to mpq");
1191      return NULL;
1192  }
1193  
1194  static MPQ_Object*
1195  GMPy_MPQ_From_RationalWithType(PyObject *obj, int xtype, CTXT_Object *context)
1196  {
1197      if (IS_TYPE_MPQ(xtype)) {
1198          Py_INCREF(obj);
1199          return (MPQ_Object*)obj;
1200      }
1201  
1202      if (IS_TYPE_MPZ(xtype))
1203          return GMPy_MPQ_From_MPZ((MPZ_Object*)obj, context);
1204  
1205      if (IS_TYPE_PyInteger(xtype))
1206          return GMPy_MPQ_From_PyIntOrLong(obj, context);
1207  
1208      if (IS_TYPE_XMPZ(xtype))
1209          return GMPy_MPQ_From_XMPZ((XMPZ_Object*)obj, context);
1210  
1211      if (IS_TYPE_PyFraction(xtype))
1212          return GMPy_MPQ_From_Fraction(obj, context);
1213  
1214      if (IS_TYPE_HAS_MPQ(xtype)) {
1215          MPQ_Object * res = (MPQ_Object *) PyObject_CallMethod(obj, "__mpq__", NULL);
1216  
1217          if (res != NULL && MPQ_Check(res)) {
1218              return res;
1219          }
1220          else {
1221              Py_XDECREF((PyObject*)res);
1222              goto error;
1223          }
1224      }
1225  
1226      if (IS_TYPE_HAS_MPZ(xtype)) {
1227          MPZ_Object * res = (MPZ_Object *) PyObject_CallMethod(obj, "__mpz__", NULL);
1228  
1229          if (res != NULL && MPZ_Check(res)) {
1230              MPQ_Object * temp = GMPy_MPQ_From_MPZ(res, context);
1231              Py_DECREF(res);
1232              return temp;
1233          }
1234          else {
1235              Py_XDECREF((PyObject*)res);
1236              goto error;
1237          }
1238      }
1239  
1240    error:
1241      TYPE_ERROR("cannot convert object to mpq");
1242      return NULL;
1243  }
1244  
1245  /*
1246   * coerce any number to a mpq
1247   */
1248  
1249  #ifdef SHARED
1250  /* Helper function for argument parsing. Not used in static build. */
1251  
1252  int
1253  GMPy_MPQ_ConvertArg(PyObject *arg, PyObject **ptr)
1254  {
1255      MPQ_Object* result = GMPy_MPQ_From_NumberWithType(arg, GMPy_ObjectType(arg), NULL);
1256  
1257      if (result) {
1258          *ptr = (PyObject*)result;
1259          return 1;
1260      }
1261      else {
1262          if (!PyErr_Occurred()) {
1263              TYPE_ERROR("argument can not be converted to 'mpq'");
1264          }
1265          return 0;
1266      }
1267  }
1268  
1269  #endif
1270  
1271  /* str and repr implementations for mpq */
1272  static PyObject *
1273  GMPy_MPQ_Str_Slot(MPQ_Object *self)
1274  {
1275      /* base-10, no tag */
1276      return GMPy_PyStr_From_MPQ(self, 10, 0, NULL);
1277  }
1278  
1279  static PyObject *
1280  GMPy_MPQ_Repr_Slot(MPQ_Object *self)
1281  {
1282      /* base-10, with tag */
1283      return GMPy_PyStr_From_MPQ(self, 10, 1, NULL);
1284  }
1285