diff options
author | Antoine Pitrou <antoine@python.org> | 2015-09-01 15:50:07 +0200 |
---|---|---|
committer | Antoine Pitrou <antoine@python.org> | 2015-09-01 16:24:27 +0200 |
commit | ad1f7cb18f24d6807708889753556236b076ea5d (patch) | |
tree | 70a36d6b00ab723d57e6b9e6cce3373f8c1ce4b7 /numpy/core/src/umath/loops.c.src | |
parent | d750cba93436f20d5457daec5ad5d5ffb65f22bd (diff) | |
download | python-numpy-ad1f7cb18f24d6807708889753556236b076ea5d.tar.gz python-numpy-ad1f7cb18f24d6807708889753556236b076ea5d.tar.bz2 python-numpy-ad1f7cb18f24d6807708889753556236b076ea5d.zip |
BUG: fix timedelta arithmetic with invalid values or NaTs
Timedelta multiplication and division relied on undefined behaviour for some
inputs, which would give the expected results on x86 but not on armv7l
(e.g. Raspberry Pi 2). Closes #6274.
Diffstat (limited to 'numpy/core/src/umath/loops.c.src')
-rw-r--r-- | numpy/core/src/umath/loops.c.src | 26 |
1 files changed, 19 insertions, 7 deletions
diff --git a/numpy/core/src/umath/loops.c.src b/numpy/core/src/umath/loops.c.src index 36046d9b8..e57dd5bd0 100644 --- a/numpy/core/src/umath/loops.c.src +++ b/numpy/core/src/umath/loops.c.src @@ -1286,11 +1286,17 @@ TIMEDELTA_md_m_multiply(char **args, npy_intp *dimensions, npy_intp *steps, void BINARY_LOOP { const npy_timedelta in1 = *(npy_timedelta *)ip1; const double in2 = *(double *)ip2; - if (in1 == NPY_DATETIME_NAT || npy_isnan(in2)) { + if (in1 == NPY_DATETIME_NAT) { *((npy_timedelta *)op1) = NPY_DATETIME_NAT; } else { - *((npy_timedelta *)op1) = (npy_timedelta)(in1 * in2); + double result = in1 * in2; + if (npy_isfinite(result)) { + *((npy_timedelta *)op1) = (npy_timedelta)result; + } + else { + *((npy_timedelta *)op1) = NPY_DATETIME_NAT; + } } } } @@ -1301,11 +1307,17 @@ TIMEDELTA_dm_m_multiply(char **args, npy_intp *dimensions, npy_intp *steps, void BINARY_LOOP { const double in1 = *(double *)ip1; const npy_timedelta in2 = *(npy_timedelta *)ip2; - if (npy_isnan(in1) || in2 == NPY_DATETIME_NAT) { + if (in2 == NPY_DATETIME_NAT) { *((npy_timedelta *)op1) = NPY_DATETIME_NAT; } else { - *((npy_timedelta *)op1) = (npy_timedelta)(in1 * in2); + double result = in1 * in2; + if (npy_isfinite(result)) { + *((npy_timedelta *)op1) = (npy_timedelta)result; + } + else { + *((npy_timedelta *)op1) = NPY_DATETIME_NAT; + } } } } @@ -1337,11 +1349,11 @@ TIMEDELTA_md_m_divide(char **args, npy_intp *dimensions, npy_intp *steps, void * } else { double result = in1 / in2; - if (npy_isnan(result)) { - *((npy_timedelta *)op1) = NPY_DATETIME_NAT; + if (npy_isfinite(result)) { + *((npy_timedelta *)op1) = (npy_timedelta)result; } else { - *((npy_timedelta *)op1) = (npy_timedelta)(result); + *((npy_timedelta *)op1) = NPY_DATETIME_NAT; } } } |