source: sage/ext/mpz_pylong.c @ 5781:0a837401a64f

Revision 5781:0a837401a64f, 1.7 KB checked in by William Stein <wstein@…>, 6 years ago (diff)

David Harvey: add new mpz_get_pyintlong() function which returns either python int (fast!) or python long if it doesn't fit; change some Integer methods to use this new function

Line 
1/* mpz <-> pylong conversion and "pythonhash" for mpz
2 *
3 * Author:  Gonzalo Tornaría <tornaria@math.utexas.edu>
4 * Date:    March 2006
5 * License: GPL v2
6 *
7 * this is free software: if it breaks, you get to keep all the pieces
8
9AUTHORS:
10  -- David Harvey (2007-08-18): added mpz_get_pyintlong function
11
12 */
13
14#include "mpn_pylong.h"
15#include "mpz_pylong.h"
16
17/* mpz python hash */
18long
19mpz_pythonhash (mpz_srcptr z)
20{
21  long x = mpn_pythonhash(z->_mp_d, abs(z->_mp_size));
22  if (z->_mp_size < 0)
23    x = -x;
24  if (x == -1)
25    x = -2;
26  return x;
27}
28
29/* mpz -> pylong conversion */
30PyObject *
31mpz_get_pylong(mpz_srcptr z)
32{
33  py_size_t size = mpn_pylong_size(z->_mp_d, abs(z->_mp_size));
34  PyLongObject *l = PyObject_NEW_VAR(PyLongObject, &PyLong_Type, size);
35
36  if (l != NULL)
37  {
38    mpn_get_pylong(l->ob_digit, size, z->_mp_d, abs(z->_mp_size));
39    if (z->_mp_size < 0)
40      l->ob_size = -(l->ob_size);
41  }
42
43  return (PyObject *) l;
44}
45
46/* mpz -> pyint/pylong conversion; if the value fits in a python int, it
47returns a python int (optimised for that pathway), otherwise returns
48a python long */
49PyObject *
50mpz_get_pyintlong(mpz_srcptr z)
51{
52  if (mpz_fits_slong_p(z))
53     return PyInt_FromLong(mpz_get_si(z));
54
55  return mpz_get_pylong(z);
56}
57
58/* pylong -> mpz conversion */
59int
60mpz_set_pylong(mpz_ptr z, PyObject * ll)
61{
62  register PyLongObject * l = (PyLongObject *) ll;
63  mp_size_t size;
64  int i;
65
66  if (l==NULL || !PyLong_Check(l)) {
67    PyErr_BadInternalCall();
68    return -1;
69  }
70 
71  size = mpn_size_from_pylong(l->ob_digit, abs(l->ob_size));
72
73  if (z->_mp_alloc < size)
74    _mpz_realloc (z, size);
75
76  mpn_set_pylong(z->_mp_d, size, l->ob_digit, abs(l->ob_size));
77  z->_mp_size = l->ob_size < 0 ? -size : size;
78
79  return size;
80}
Note: See TracBrowser for help on using the repository browser.