summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--numpy/core/src/umath/loops.c.src16
-rw-r--r--numpy/core/tests/test_umath.py42
2 files changed, 40 insertions, 18 deletions
diff --git a/numpy/core/src/umath/loops.c.src b/numpy/core/src/umath/loops.c.src
index d747864f8..14076f3fa 100644
--- a/numpy/core/src/umath/loops.c.src
+++ b/numpy/core/src/umath/loops.c.src
@@ -838,9 +838,9 @@ NPY_NO_EXPORT void
@TYPE@_logical_xor(char **args, npy_intp *dimensions, npy_intp *steps, void *NPY_UNUSED(func))
{
BINARY_LOOP {
- const @type@ in1 = *(@type@ *)ip1;
- const @type@ in2 = *(@type@ *)ip2;
- *((npy_bool *)op1)= (in1 && !in2) || (!in1 && in2);
+ const int t1 = !!*(@type@ *)ip1;
+ const int t2 = !!*(@type@ *)ip2;
+ *((npy_bool *)op1) = (t1 != t2);
}
}
@@ -1515,9 +1515,9 @@ NPY_NO_EXPORT void
@TYPE@_logical_xor(char **args, npy_intp *dimensions, npy_intp *steps, void *NPY_UNUSED(func))
{
BINARY_LOOP {
- const @type@ in1 = *(@type@ *)ip1;
- const @type@ in2 = *(@type@ *)ip2;
- *((npy_bool *)op1)= (in1 && !in2) || (!in1 && in2);
+ const int t1 = !!*(@type@ *)ip1;
+ const int t2 = !!*(@type@ *)ip2;
+ *((npy_bool *)op1) = (t1 != t2);
}
}
@@ -1864,7 +1864,7 @@ HALF_logical_xor(char **args, npy_intp *dimensions, npy_intp *steps, void *NPY_U
BINARY_LOOP {
const int in1 = !npy_half_iszero(*(npy_half *)ip1);
const int in2 = !npy_half_iszero(*(npy_half *)ip2);
- *((npy_bool *)op1)= (in1 && !in2) || (!in1 && in2);
+ *((npy_bool *)op1) = (in1 != in2);
}
}
@@ -2346,7 +2346,7 @@ NPY_NO_EXPORT void
const @ftype@ in2i = ((@ftype@ *)ip2)[1];
const npy_bool tmp1 = (in1r || in1i);
const npy_bool tmp2 = (in2r || in2i);
- *((npy_bool *)op1) = (tmp1 && !tmp2) || (!tmp1 && tmp2);
+ *((npy_bool *)op1) = tmp1 != tmp2;
}
}
diff --git a/numpy/core/tests/test_umath.py b/numpy/core/tests/test_umath.py
index 1cba24d06..4bbf5601a 100644
--- a/numpy/core/tests/test_umath.py
+++ b/numpy/core/tests/test_umath.py
@@ -720,21 +720,43 @@ class TestFmin(_FilterInvalids):
class TestBool(TestCase):
- def test_truth_table(self):
+ def test_truth_table_logical(self):
+ # 2, 3 and 4 serves as true values
+ input1 = [0, 0, 3, 2]
+ input2 = [0, 4, 0, 2]
+
+ typecodes = (np.typecodes['AllFloat']
+ + np.typecodes['AllInteger']
+ + '?') # boolean
+ for dtype in map(np.dtype, typecodes):
+ arg1 = np.asarray(input1, dtype=dtype)
+ arg2 = np.asarray(input2, dtype=dtype)
+
+ # OR
+ out = [False, True, True, True]
+ for func in (np.logical_or, np.maximum):
+ assert_equal(func(arg1, arg2).astype(bool), out)
+ # AND
+ out = [False, False, False, True]
+ for func in (np.logical_and, np.minimum):
+ assert_equal(func(arg1, arg2).astype(bool), out)
+ # XOR
+ out = [False, True, True, False]
+ for func in (np.logical_xor, np.not_equal):
+ assert_equal(func(arg1, arg2).astype(bool), out)
+
+ def test_truth_table_bitwise(self):
arg1 = [False, False, True, True]
arg2 = [False, True, False, True]
- # OR
+
out = [False, True, True, True]
- for func in (np.logical_or, np.bitwise_or, np.maximum):
- assert_equal(func(arg1, arg2), out)
- # AND
+ assert_equal(np.bitwise_or(arg1, arg2), out)
+
out = [False, False, False, True]
- for func in (np.logical_and, np.bitwise_and, np.minimum):
- assert_equal(func(arg1, arg2), out)
- # XOR
+ assert_equal(np.bitwise_and(arg1, arg2), out)
+
out = [False, True, True, False]
- for func in (np.logical_xor, np.bitwise_xor, np.not_equal):
- assert_equal(func(arg1, arg2), out)
+ assert_equal(np.bitwise_xor(arg1, arg2), out)
class TestFloatingPoint(TestCase):