Skip to content

Commit 86b4d85

Browse files
fixed issues with remainder and spacing umath functions found
by NumPy test suite after patching
1 parent 5d73c43 commit 86b4d85

File tree

1 file changed

+56
-12
lines changed

1 file changed

+56
-12
lines changed

mkl_umath/src/loops_intel.c.src

Lines changed: 56 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -114,28 +114,72 @@
114114
#include <stdio.h>
115115

116116
static inline npy_double spacing(npy_double x) {
117-
return nextafter(x, HUGE_VAL) - x;
117+
if (isinf(x))
118+
return ((npy_double) NAN);
119+
return copysign(nextafter(fabs(x), ((npy_double) INFINITY)), x) - x;
118120
}
119121

120122
static inline npy_float spacingf(npy_float x) {
121-
return nextafterf(x, HUGE_VALF) - x;
123+
if (isinff(x))
124+
return ((npy_float) NAN);
125+
126+
return copysignf(nextafterf(fabsf(x), INFINITY), x) - x;
122127
}
123128

124-
static inline npy_double divmod(npy_double x1, npy_double x2, npy_double *mod) {
125-
npy_double q = floor(x1 / x2);
126129

127-
*mod = x1 - q * x2;
130+
/**begin repeat
131+
* Float types
132+
* #type = npy_float, npy_double#
133+
* #c = f, #
134+
*/
135+
/*
136+
* Python version of divmod.
137+
*
138+
* The implementation is mostly copied from cpython 3.5.
139+
*/
140+
static inline @type@
141+
divmod@c@(@type@ a, @type@ b, @type@ *modulus)
142+
{
143+
@type@ div, mod, floordiv;
128144

129-
return q;
130-
}
145+
mod = fmod@c@(a, b);
131146

132-
static inline npy_float divmodf(npy_float x1, npy_float x2, npy_float *mod) {
133-
npy_float q = floorf(x1 / x2);
147+
if (!b) {
148+
/* If b == 0, return result of fmod. For IEEE is nan */
149+
*modulus = mod;
150+
return mod;
151+
}
134152

135-
*mod = x1 - q * x2;
153+
/* a - mod should be very nearly an integer multiple of b */
154+
div = (a - mod) / b;
136155

137-
return q;
156+
/* adjust fmod result to conform to Python convention of remainder */
157+
if (mod) {
158+
if ((b < 0) != (mod < 0)) {
159+
mod += b;
160+
div -= 1.0@c@;
161+
}
162+
}
163+
else {
164+
/* if mod is zero ensure correct sign */
165+
mod = copysign@c@(0, b);
166+
}
167+
168+
/* snap quotient to nearest integral value */
169+
if (div) {
170+
floordiv = floor@c@(div);
171+
if (div - floordiv > 0.5@c@)
172+
floordiv += 1.0@c@;
173+
}
174+
else {
175+
/* if div is zero ensure correct sign */
176+
floordiv = copysign@c@(0, a/b);
177+
}
178+
179+
*modulus = mod;
180+
return floordiv;
138181
}
182+
/**end repeat**/
139183

140184
/*
141185
*****************************************************************************
@@ -1732,7 +1776,7 @@ NPY_NO_EXPORT void
17321776
{
17331777
UNARY_LOOP {
17341778
const @type@ in1 = *(@type@ *)ip1;
1735-
*((@type@ *)op1) = (nextafter@c@(in1, HUGE_VAL)) - in1;
1779+
*((@type@ *)op1) = (spacing@c@(in1));
17361780
}
17371781
}
17381782

0 commit comments

Comments
 (0)