summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCharles Harris <charlesr.harris@gmail.com>2016-02-15 17:58:25 -0700
committerCharles Harris <charlesr.harris@gmail.com>2016-02-18 21:31:05 -0700
commit735174b88768999a2247f960669185978587408a (patch)
tree11406be9616ac7976d386a81c4b4ec8f5eaab39d
parentfbeae17e5db78d5c7607bc21f16f6dcdb635c18e (diff)
downloadnumpy-735174b88768999a2247f960669185978587408a.tar.gz
ENH: Make numpy ufuncs compatible with Python divmod.
The following numpy ufuncs are reimplemented using the npy_divmod function. - remainder ('%') - floor_divide ('//') Example of differences Currently In [1]: a = np.array(78 * 6e-8) In [2]: b = np.array(6e-8) In [3]: a // b Out[3]: 77.0 In [4]: a % b Out[4]: 5.9999999999999651e-08 Previously In [1]: a = np.array(78 * 6e-8) In [2]: b = np.array(6e-8) In [3]: a // b Out[3]: 78.0 In [4]: a % b Out[4]: 0.0 The first agrees with the Python values for the same operation and is a bit more accurate for the input values as represented internally. Closes #7224.
-rw-r--r--numpy/core/src/umath/loops.c.src25
1 files changed, 10 insertions, 15 deletions
diff --git a/numpy/core/src/umath/loops.c.src b/numpy/core/src/umath/loops.c.src
index 7b8dcdbaf..0d9806f5d 100644
--- a/numpy/core/src/umath/loops.c.src
+++ b/numpy/core/src/umath/loops.c.src
@@ -1696,7 +1696,8 @@ NPY_NO_EXPORT void
BINARY_LOOP {
const @type@ in1 = *(@type@ *)ip1;
const @type@ in2 = *(@type@ *)ip2;
- *((@type@ *)op1) = npy_floor@c@(in1/in2);
+ @type@ mod;
+ *((@type@ *)op1) = npy_divmod@c@(in1, in2, &mod);
}
}
@@ -1706,8 +1707,7 @@ NPY_NO_EXPORT void
BINARY_LOOP {
const @type@ in1 = *(@type@ *)ip1;
const @type@ in2 = *(@type@ *)ip2;
- const @type@ div = in1/in2;
- *((@type@ *)op1) = in2*(div - npy_floor@c@(div));
+ npy_divmod@c@(in1, in2, (@type@ *)op1);
}
}
@@ -2011,9 +2011,10 @@ NPY_NO_EXPORT void
HALF_floor_divide(char **args, npy_intp *dimensions, npy_intp *steps, void *NPY_UNUSED(func))
{
BINARY_LOOP {
- const float in1 = npy_half_to_float(*(npy_half *)ip1);
- const float in2 = npy_half_to_float(*(npy_half *)ip2);
- *((npy_half *)op1) = npy_float_to_half(npy_floorf(in1/in2));
+ const npy_half in1 = *(npy_half *)ip1;
+ const npy_half in2 = *(npy_half *)ip2;
+ npy_half mod;
+ *((npy_half *)op1) = npy_half_divmod(in1, in2, &mod);
}
}
@@ -2021,15 +2022,9 @@ NPY_NO_EXPORT void
HALF_remainder(char **args, npy_intp *dimensions, npy_intp *steps, void *NPY_UNUSED(func))
{
BINARY_LOOP {
- const float in1 = npy_half_to_float(*(npy_half *)ip1);
- const float in2 = npy_half_to_float(*(npy_half *)ip2);
- const float res = npy_fmodf(in1,in2);
- if (res && ((in2 < 0) != (res < 0))) {
- *((npy_half *)op1) = npy_float_to_half(res + in2);
- }
- else {
- *((npy_half *)op1) = npy_float_to_half(res);
- }
+ const npy_half in1 = *(npy_half *)ip1;
+ const npy_half in2 = *(npy_half *)ip2;
+ npy_half_divmod(in1, in2, (npy_half *)op1);
}
}