8000 BUG: core: nonzero() requires swap for float types · numpy/numpy@6e5590f · GitHub
[go: up one dir, main page]

Skip to content

Commit 6e5590f

Browse files
mwiebecharris
authored andcommitted
BUG: core: nonzero() requires swap for float types
1 parent 12e936a commit 6e5590f

File tree

3 files changed

+18
-7
lines changed

3 files changed

+18
-7
lines changed

numpy/core/src/multiarray/arraytypes.c.src

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2231,6 +2231,7 @@ UNICODE_copyswap (char *dst, char *src, int swap, PyArrayObject *arr)
22312231
* #type = Bool, byte, ubyte, short, ushort, int, uint, long, ulong,
22322232
* longlong, ulonglong, float, double, longdouble,
22332233
* datetime, timedelta#
2234+
* #isfloat = 0*11, 1*3, 0*2#
22342235
*/
22352236
static Bool
22362237
@fname@_nonzero (char *ip, PyArrayObject *ap)
@@ -2241,11 +2242,16 @@ static Bool
22412242
}
22422243
else {
22432244
/*
2244-
* don't worry about swap, since we are just testing
2245-
* whether or not equal to 0
2245+
* Don't worry about swapping for integer types,
2246+
* since we are just testing for equality with 0.
2247+
* For float types, the signed zeros require us to swap.
22462248
*/
22472249
@type@ tmp;
2250+
#if @isfloat@
2251+
ap->descr->f->copyswap(&tmp, ip, !PyArray_ISNOTSWAPPED(ap), ap);
2252+
#else
22482253
memcpy(&tmp, ip, sizeof(@type@));
2254+
#endif
22492255
return (Bool) (tmp != 0);
22502256
}
22512257
}
@@ -2264,12 +2270,8 @@ static Bool
22642270
return (Bool) ((ptmp->real != 0) || (ptmp->imag != 0));
22652271
}
22662272
else {
2267-
/*
2268-
* don't worry about swap, since we are just testing
2269-
* whether or not equal to 0
2270-
*/
22712273
@type@ tmp;
2272-
memcpy(&tmp, ip, sizeof(@type@));
2274+
ap->descr->f->copyswap(&tmp, ip, !PyArray_ISNOTSWAPPED(ap), ap);
22732275
return (Bool) ((tmp.real != 0) || (tmp.imag != 0));
22742276
}
22752277
}

numpy/core/src/multiarray/item_selection.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line c 8000 hange
@@ -1697,6 +1697,7 @@ PyArray_Nonzero(PyArrayObject *self)
16971697
if (it == NULL) {
16981698
return NULL;
16991699
}
1700+
/* One pass through 'self', counting the non-zero elements */
17001701
size = it->size;
17011702
for (i = 0; i < size; i++) {
17021703
if (self->descr->f->nonzero(it->dataptr, self)) {
@@ -1706,6 +1707,7 @@ PyArray_Nonzero(PyArrayObject *self)
17061707
}
17071708

17081709
PyArray_ITER_RESET(it);
1710+
/* Allocate the tuple of coordinates */
17091711
ret = PyTuple_New(n);
17101712
if (ret == NULL) {
17111713
goto fail;
@@ -1720,6 +1722,7 @@ PyArray_Nonzero(PyArrayObject *self)
17201722
PyTuple_SET_ITEM(ret, j, item);
17211723
dptr[j] = (intp *)PyArray_DATA(item);
17221724
}
1725+
/* A second pass through 'self', recording the indices */
17231726
if (n == 1) {
17241727
for (i = 0; i < size; i++) {
17251728
if (self->descr->f->nonzero(it->dataptr, self)) {

numpy/core/tests/test_regression.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1434,6 +1434,12 @@ def test_eq_string_and_object_array(self):
14341434
assert_array_equal(a1 == a2, [True, False])
14351435
assert_array_equal(a2 == a1, [True, False])
14361436

1437+
def test_nonzero_byteswap(self):
1438+
a = np.array([0x80000000, 0x00000080, 0], dtype=np.uint32)
1439+
a.dtype = np.float32
1440+
assert_equal(a.nonzero()[0], [1])
1441+
a = a.byteswap().newbyteorder()
1442+
assert_equal(a.nonzero()[0], [1]) # [0] if nonzero() ignores swap
14371443

14381444
if __name__ == "__main__":
14391445
run_module_suite()

0 commit comments

Comments
 (0)
0