class BaseRat (object):
"""Base class implementing fields of fractions over Euclidean domains."""
def __new__(cls, a, b):
- a, b = cls.RING(a), cls.RING(b)
+ a, b = cls.RING._implicit(a), cls.RING._implicit(b)
q, r = divmod(a, b)
if r == cls.ZERO: return q
g = b.gcd(r)
return ((PyObject *)zz);
}
+#define IMPLICIT(pre) \
+ static PyObject *pre##meth__implicit(PyObject *me, PyObject *arg) \
+ { \
+ PyObject *x, *rc = 0; \
+ mp *y = MP_NEW; \
+ if (!PyArg_ParseTuple(arg, "O:_implicit", &x)) goto end; \
+ y = implicit##pre(x); \
+ if (!y) TYERR("can't convert implicitly to " #pre); \
+ rc = pre##_pywrap(y); \
+ end: \
+ return (rc); \
+ }
+IMPLICIT(mp)
+IMPLICIT(gf)
+#undef IMPLICIT
+
Py_hash_t mphash(mp *x)
{
PyObject *l = mp_topylong(x);
" Parse STR as a large integer, according to RADIX. If RADIX is\n"
" zero, read a prefix from STR to decide radix: allow `0b' for binary,\n"
" `0' or `0o' for octal, `0x' for hex, or `R_' for other radix R.")
+ SMTH (_implicit, 0)
SMTH (factorial, "factorial(I) -> I!: compute factorial")
SMTH (fibonacci, "fibonacci(I) -> F(I): compute Fibonacci number")
SMTH (loadl, "loadl(STR) -> X: read little-endian bytes")
" Parse STR as a binary polynomial, according to RADIX. If RADIX is\n"
" zero, read a prefix from STR to decide radix: allow `0b' for binary,\n"
" `0' or `0o' for octal, `0x' for hex, or `R_' for other radix R.")
+ SMTH (_implicit, 0)
SMTH (loadl, "loadl(STR) -> X: read little-endian bytes")
SMTH (loadb, "loadb(STR) -> X: read big-endian bytes")
SMTH (frombuf, "frombuf(STR) -> (X, REST): read buffer format")
def test_strconv(me):
x, y = C.MP(169), "24"
- for fn in [T.add, T.sub]:
+ for fn in [T.add, T.sub, T.div]:
me.assertRaises(TypeError, fn, x, y)
me.assertRaises(TypeError, fn, y, x)
me.assertEqual(x*y, 169*"24")
me.assertFalse(b/a > c/a)
me.assertTrue(c/a > b/a)
+ ## Conversions from string.
+ me.assertRaises(TypeError, T.add, f, "3")
+
def test_intrat(me):
me.check_rat(C.IntRat)
- ## Check string conversions.
+ ## Check interaction with floating point.
u = C.MP(5)/C.MP(4)
+ me.assertEqual(type(u + 0.0), float)
+ me.assertEqual(u, 1.25)
+ me.assertTrue(u < 1.26)
+ me.assertTrue(u > 1.24)
+
+ ## Check string conversions.
me.assertEqual(str(u), "5/4")
me.assertEqual(repr(u), "IntRat(5, 4)")
## Check string conversions.
u = C.GF(5)/C.GF(4)
+ me.assertRaises(TypeError, T.add, u, 0.0)
me.assertEqual(str(u), "0x5/0x4")
me.assertEqual(repr(u), "GFRat(0x5, 0x4)")