ec.c (ecpt_pyrichcompare): Fix point comparisons.
[catacomb-python] / mp.c
diff --git a/mp.c b/mp.c
index f5f4320..e4f5980 100644 (file)
--- a/mp.c
+++ b/mp.c
@@ -544,13 +544,15 @@ end:
   return ((PyObject *)zz);
 }
 
-static long mp_pyhash(PyObject *me)
+long mphash(mp *x)
 {
-  long h;
-  PyObject *l = mp_topylong(MP_X(me)); h = PyObject_Hash(l);
+  PyObject *l = mp_topylong(x);
+  long h = PyObject_Hash(l);
   Py_DECREF(l); return (h);
 }
 
+static long mp_pyhash(PyObject *me) { return (mphash(MP_X(me))); }
+
 static PyObject *mpmeth_jacobi(PyObject *me, PyObject *arg)
 {
   mp *y = 0;
@@ -682,6 +684,19 @@ end:
   return (z);
 }
 
+static PyObject *mpmeth_leastcongruent(PyObject *me, PyObject *arg)
+{
+  mp *z, *b, *m;
+  PyObject *rc = 0;
+
+  if (!PyArg_ParseTuple(arg, "O&O&:leastcongruent", convmp, &b, convmp, &m))
+    goto end;
+  z = mp_leastcongruent(MP_NEW, b, MP_X(me), m);
+  rc = mp_pywrap(z);
+end:
+  return (rc);
+}
+
 #define STOREOP(name, c)                                               \
   static PyObject *mpmeth_##name(PyObject *me,                         \
                                 PyObject *arg, PyObject *kw)           \
@@ -713,7 +728,7 @@ STOREOP(storeb2c, 2c)
   {                                                                    \
     buf b;                                                             \
     char *p;                                                           \
-    int sz;                                                            \
+    Py_ssize_t sz;                                                     \
     PyObject *rc = 0;                                                  \
     mp *x;                                                             \
                                                                        \
@@ -792,6 +807,8 @@ static PyMethodDef mp_pymethods[] = {
         "X.gcdx(Y) -> (gcd(X, Y), U, V) with X U + Y V = gcd(X, Y)")
   METH (modinv,        "X.modinv(Y) -> multiplicative inverse of Y mod X")
   METH (modsqrt,       "X.modsqrt(Y) -> square root of Y mod X, if X prime")
+  METH (leastcongruent,
+        "X.leastcongruent(B, M) -> smallest Z >= B with Z == X (mod M)")
   KWMETH(primep,       "X.primep(rng = rand) -> true/false if X is prime")
   KWMETH(tostring,     "X.tostring(radix = 10) -> STR")
   KWMETH(storel,       "X.storel(len = -1) -> little-endian bytes")
@@ -911,7 +928,7 @@ static PyObject *meth__MP_fromstring(PyObject *me,
 {
   int r = 0;
   char *p;
-  int len;
+  Py_ssize_t len;
   PyObject *z = 0;
   mp *zz;
   mptext_stringctx sc;
@@ -924,7 +941,8 @@ static PyObject *meth__MP_fromstring(PyObject *me,
   sc.buf = p; sc.lim = p + len;
   if ((zz = mp_read(MP_NEW, r, &mptext_stringops, &sc)) == 0)
     VALERR("bad integer");
-  z = Py_BuildValue("(Ns#)", mp_pywrap(zz), sc.buf, (int)(sc.lim - sc.buf));
+  z = Py_BuildValue("(Ns#)", mp_pywrap(zz),
+                   sc.buf, (Py_ssize_t)(sc.lim - sc.buf));
 end:
   return (z);
 }
@@ -952,7 +970,7 @@ static PyObject *meth__MP_fibonacci(PyObject *me, PyObject *arg)
   static PyObject *meth__##py##_##name(PyObject *me, PyObject *arg)    \
   {                                                                    \
     char *p;                                                           \
-    int len;                                                           \
+    Py_ssize_t len;                                                    \
     if (!PyArg_ParseTuple(arg, "Os#:" #name, &me, &p, &len)) return (0); \
     return (pre##_pywrap(mp_##name(MP_NEW, p, len)));                  \
   }
@@ -1869,15 +1887,6 @@ end:
   return ((PyObject *)zz);
 }
 
-static long gf_pyhash(PyObject *me)
-{
-  long i = mp_tolong(MP_X(me));
-  i ^= 0xc7ecd67c; /* random perturbance */
-  if (i == -1)
-    i = -2;
-  return (i);
-}
-
 static PyObject *gf_pyexp(PyObject *x, PyObject *y, PyObject *z)
 {
   mp *xx = 0, *yy = 0, *zz = 0;
@@ -2060,7 +2069,7 @@ static PyTypeObject gf_pytype_skel = {
   &gf_pynumber,                                /* @tp_as_number@ */
   0,                                   /* @tp_as_sequence@ */
   0,                                   /* @tp_as_mapping@ */
-  gf_pyhash,                           /* @tp_hash@ */
+  mp_pyhash,                           /* @tp_hash@ */
   0,                                   /* @tp_call@ */
   mp_pyhex,                            /* @tp_str@ */
   0,                                   /* @tp_getattro@ */
@@ -2111,7 +2120,7 @@ static PyObject *meth__GF_fromstring(PyObject *me,
 {
   int r = 0;
   char *p;
-  int len;
+  Py_ssize_t len;
   PyObject *z = 0;
   mp *zz;
   mptext_stringctx sc;
@@ -2127,7 +2136,8 @@ static PyObject *meth__GF_fromstring(PyObject *me,
     if (zz) MP_DROP(zz);
     VALERR("bad binary polynomial");
   }
-  z = Py_BuildValue("(Ns#)", gf_pywrap(zz), sc.buf, (int)(sc.lim - sc.buf));
+  z = Py_BuildValue("(Ns#)", gf_pywrap(zz),
+                   sc.buf, (Py_ssize_t)(sc.lim - sc.buf));
 end:
   return (z);
 }