numexpr icon indicating copy to clipboard operation
numexpr copied to clipboard

Python semantics for mod of negative int

Open jbrockmendel opened this issue 5 years ago • 2 comments

arr = np.array([-2, -2])
result = ne.evaluate("arr % 4")
expected = arr % 4

>>> result
array([-2, -2], dtype=int64)
>>> expected
array([2, 2])

AFAICT ne.evaluate is using C semantics for divmod, rounding the div towards zero instead of towards -inf. It would be nice if we could enable python semantics here, analogous to @cython.cdivision(False)

jbrockmendel avatar Sep 18 '20 03:09 jbrockmendel

Well it's not practical to add new op-codes in version 2.7, as they're all used up. So it would imply changing the behavior of NumExpr to use the sign of the divisor to remain consistent in the Python eco-system. I'm inclined to change it because NumExpr isn't consistent, if you use literals,

ne.evaluate('-2 % 4')

the result is the expected Python value 2. If you using floating-point, it also works how Python does:

arr = np.array([-2, -2], dtype=np.float32)
result = ne.evaluate("arr % 4")
expected = arr % 4

>>> result
array([2., 2.], dtype=float32)
>>> expected
array([2., 2.], dtype=float32)

The actual functions are as follows; for integer mod (from numexpr/interp_body.cpp):

case OP_MOD_LLL: VEC_ARG2(l_dest = l2 ? (l1 % l2) : 0);

and for floating-point mod:

case OP_MOD_DDD: VEC_ARG2(d_dest = d1 - floor(d1/d2) * d2);

So basically I need a macro for copysign that works for ints. One possible implementation:

#define COPYSIGN_INT(X, Y) (Y > 0 ? (X < 0 ? -X : X) : (X < 0 ? X : -X))

case OP_MOD_LLL: VEC_ARG2(l_dest = COPYSIGN_INT(l2 ? (l1 % l2) : 0, l2));

This is ugly, there's probably a faster implementation out there somewhere.

robbmcleod avatar Sep 22 '20 00:09 robbmcleod

The implementation of copysign for double makes use of the sign bit:

http://www.netlib.org/fdlibm/s_copysign.c

I'm guessing there's some slick way to do it with bit-shift operations for integers. NumPy's implementation appears to be rather naive:

https://github.com/numpy/numpy/edit/master/numpy/core/src/npymath/npy_math_internal.h.src

robbmcleod avatar Sep 22 '20 00:09 robbmcleod

Message to comment on stale issues. If none provided, will not mark issues stale

github-actions[bot] avatar Feb 18 '24 01:02 github-actions[bot]