Skip to content

Commit 181f4e8

Browse files
committed
Support float/complex operands
1 parent 1cc63da commit 181f4e8

File tree

1 file changed

+140
-12
lines changed

1 file changed

+140
-12
lines changed

main.c

Lines changed: 140 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2177,6 +2177,9 @@ str(PyObject *self)
21772177
return MPZ_to_str((MPZ_Object *)self, 10, 0);
21782178
}
21792179

2180+
#define Number_Check(op) (PyFloat_Check((op)) \
2181+
|| PyComplex_Check((op)))
2182+
21802183
#define CHECK_OP(u, a) \
21812184
if (MPZ_Check(a)) { \
21822185
u = (MPZ_Object *)a; \
@@ -2188,10 +2191,15 @@ str(PyObject *self)
21882191
goto end; \
21892192
} \
21902193
} \
2194+
else if (Number_Check(a)) { \
2195+
goto numbers; \
2196+
} \
21912197
else { \
21922198
goto fallback; \
21932199
}
21942200

2201+
static PyObject * to_float(PyObject *self);
2202+
21952203
static PyObject *
21962204
richcompare(PyObject *self, PyObject *other, int op)
21972205
{
@@ -2229,6 +2237,39 @@ richcompare(PyObject *self, PyObject *other, int op)
22292237
Py_XDECREF(u);
22302238
Py_XDECREF(v);
22312239
Py_RETURN_NOTIMPLEMENTED;
2240+
numbers:
2241+
Py_XDECREF(u);
2242+
Py_XDECREF(v);
2243+
2244+
PyObject *uf, *vf;
2245+
2246+
if (Number_Check(self)) {
2247+
uf = self;
2248+
Py_INCREF(uf);
2249+
}
2250+
else {
2251+
uf = to_float(self);
2252+
if (!uf) {
2253+
return NULL;
2254+
}
2255+
}
2256+
if (Number_Check(other)) {
2257+
vf = other;
2258+
Py_INCREF(vf);
2259+
}
2260+
else {
2261+
vf = to_float(other);
2262+
if (!vf) {
2263+
Py_DECREF(uf);
2264+
return NULL;
2265+
}
2266+
}
2267+
2268+
PyObject *res = PyObject_RichCompare(uf, vf, op);
2269+
2270+
Py_DECREF(uf);
2271+
Py_DECREF(vf);
2272+
return res;
22322273
}
22332274

22342275
static Py_hash_t
@@ -2308,7 +2349,7 @@ to_bool(PyObject *self)
23082349
return ((MPZ_Object *)self)->size != 0;
23092350
}
23102351

2311-
#define BINOP(suff) \
2352+
#define BINOP_INT(suff) \
23122353
static PyObject * \
23132354
nb_##suff(PyObject *self, PyObject *other) \
23142355
{ \
@@ -2324,14 +2365,67 @@ to_bool(PyObject *self)
23242365
Py_XDECREF(v); \
23252366
return res; \
23262367
fallback: \
2368+
numbers: \
23272369
Py_XDECREF(u); \
23282370
Py_XDECREF(v); \
23292371
Py_RETURN_NOTIMPLEMENTED; \
23302372
}
23312373

2332-
BINOP(add)
2333-
BINOP(sub)
2334-
BINOP(mul)
2374+
#define BINOP(suff, slot) \
2375+
static PyObject * \
2376+
nb_##suff(PyObject *self, PyObject *other) \
2377+
{ \
2378+
PyObject *res = NULL; \
2379+
MPZ_Object *u = NULL, *v = NULL; \
2380+
\
2381+
CHECK_OP(u, self); \
2382+
CHECK_OP(v, other); \
2383+
\
2384+
res = (PyObject *)MPZ_##suff(u, v); \
2385+
end: \
2386+
Py_XDECREF(u); \
2387+
Py_XDECREF(v); \
2388+
return res; \
2389+
fallback: \
2390+
Py_XDECREF(u); \
2391+
Py_XDECREF(v); \
2392+
Py_RETURN_NOTIMPLEMENTED; \
2393+
numbers: \
2394+
Py_XDECREF(u); \
2395+
Py_XDECREF(v); \
2396+
\
2397+
PyObject *uf, *vf; \
2398+
\
2399+
if (Number_Check(self)) { \
2400+
uf = self; \
2401+
Py_INCREF(uf); \
2402+
} \
2403+
else { \
2404+
uf = to_float(self); \
2405+
if (!uf) { \
2406+
return NULL; \
2407+
} \
2408+
} \
2409+
if (Number_Check(other)) { \
2410+
vf = other; \
2411+
Py_INCREF(vf); \
2412+
} \
2413+
else { \
2414+
vf = to_float(other); \
2415+
if (!vf) { \
2416+
Py_DECREF(uf); \
2417+
return NULL; \
2418+
} \
2419+
} \
2420+
res = slot(uf, vf); \
2421+
Py_DECREF(uf); \
2422+
Py_DECREF(vf); \
2423+
return res; \
2424+
}
2425+
2426+
BINOP(add, PyNumber_Add)
2427+
BINOP(sub, PyNumber_Subtract)
2428+
BINOP(mul, PyNumber_Multiply)
23352429

23362430
static PyObject *
23372431
divmod(PyObject *self, PyObject *other)
@@ -2367,20 +2461,21 @@ divmod(PyObject *self, PyObject *other)
23672461
return NULL;
23682462
/* LCOV_EXCL_STOP */
23692463
fallback:
2464+
numbers:
23702465
Py_DECREF(res);
23712466
Py_XDECREF(u);
23722467
Py_XDECREF(v);
23732468
Py_RETURN_NOTIMPLEMENTED;
23742469
}
23752470

2376-
BINOP(quot)
2377-
BINOP(rem)
2378-
BINOP(truediv)
2379-
BINOP(lshift)
2380-
BINOP(rshift)
2381-
BINOP(and)
2382-
BINOP(or)
2383-
BINOP(xor)
2471+
BINOP(quot, PyNumber_FloorDivide)
2472+
BINOP(rem, PyNumber_Remainder)
2473+
BINOP(truediv, PyNumber_TrueDivide)
2474+
BINOP_INT(lshift)
2475+
BINOP_INT(rshift)
2476+
BINOP_INT(and)
2477+
BINOP_INT(or)
2478+
BINOP_INT(xor)
23842479

23852480
static PyObject *
23862481
power(PyObject *self, PyObject *other, PyObject *module)
@@ -2522,6 +2617,39 @@ power(PyObject *self, PyObject *other, PyObject *module)
25222617
Py_XDECREF(u);
25232618
Py_XDECREF(v);
25242619
Py_RETURN_NOTIMPLEMENTED;
2620+
numbers:
2621+
Py_XDECREF(u);
2622+
Py_XDECREF(v);
2623+
2624+
PyObject *uf, *vf;
2625+
2626+
if (Number_Check(self)) {
2627+
uf = self;
2628+
Py_INCREF(uf);
2629+
}
2630+
else {
2631+
uf = to_float(self);
2632+
if (!uf) {
2633+
return NULL;
2634+
}
2635+
}
2636+
if (Number_Check(other)) {
2637+
vf = other;
2638+
Py_INCREF(vf);
2639+
}
2640+
else {
2641+
vf = to_float(other);
2642+
if (!vf) {
2643+
Py_DECREF(uf);
2644+
return NULL;
2645+
}
2646+
}
2647+
2648+
PyObject *res2 = PyNumber_Power(uf, vf, Py_None);
2649+
2650+
Py_DECREF(uf);
2651+
Py_DECREF(vf);
2652+
return res2;
25252653
}
25262654

25272655
static PyNumberMethods as_number = {

0 commit comments

Comments
 (0)