Skip to content

Commit 34f0dba

Browse files
committed
fix conflict
2 parents 4f81196 + c9dca2b commit 34f0dba

3 files changed

Lines changed: 65 additions & 4 deletions

File tree

src/csrc/casts.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1216,7 +1216,7 @@ inline npy_bool
12161216
from_quad<spec_npy_bool>(const quad_value *x, QuadBackendType backend)
12171217
{
12181218
if (backend == BACKEND_SLEEF) {
1219-
return Sleef_cast_to_int64q1(x->sleef_value) != 0;
1219+
return !Sleef_icmpeqq1(x->sleef_value, QUAD_PRECISION_ZERO);
12201220
}
12211221
else {
12221222
return x->longdouble_value != 0;

src/csrc/scalar_ops.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ extern "C" {
1717
#include "ops.hpp"
1818
#include "scalar_ops.h"
1919
#include "quad_common.h"
20+
#include "constants.hpp"
2021

2122
template <unary_op_quad_def sleef_op, unary_op_longdouble_def longdouble_op>
2223
static PyObject *
@@ -36,14 +37,14 @@ quad_unary_func(QuadPrecisionObject *self)
3637
return (PyObject *)res;
3738
}
3839

39-
PyObject *
40+
int
4041
quad_nonzero(QuadPrecisionObject *self)
4142
{
4243
if (self->backend == BACKEND_SLEEF) {
43-
return PyBool_FromLong(Sleef_icmpneq1(self->value.sleef_value, Sleef_cast_from_int64q1(0)));
44+
return !Sleef_icmpeqq1(self->value.sleef_value, QUAD_PRECISION_ZERO);
4445
}
4546
else {
46-
return PyBool_FromLong(self->value.longdouble_value != 0.0L);
47+
return self->value.longdouble_value != 0.0L;
4748
}
4849
}
4950

tests/test_quaddtype.py

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1554,6 +1554,66 @@ def test_bool_0d_array(val, expected):
15541554
# This should not segfault
15551555
result = bool(arr_0d)
15561556
assert result == expected, f"bool(np.array(QuadPrecision({val}))) should be {expected}, got {result}"
1557+
1558+
@pytest.mark.parametrize("val", [
1559+
# Small positive values that truncate to 0 when cast to int
1560+
0.5, 0.1, 0.01, 0.001, 0.0001,
1561+
1e-10, 1e-50, 1e-100, 1e-300,
1562+
# Small negative values
1563+
-0.5, -0.1, -0.01, -0.001, -0.0001,
1564+
-1e-10, -1e-50, -1e-100, -1e-300,
1565+
# Values just above/below 1
1566+
0.9999999999, 1.0000000001,
1567+
# Regular non-zero values (sanity check)
1568+
1.0, -1.0, 2.0, 100.0, 1e10,
1569+
])
1570+
def test_bool_cast_small_nonzero_values_are_truthy(val):
1571+
"""
1572+
Test that small non-zero values correctly cast to True.
1573+
1574+
This tests for a bug where casting to bool via int truncation
1575+
would make small values like 0.5 falsely become False.
1576+
"""
1577+
quad_val = QuadPrecision(str(val))
1578+
1579+
# Cast to bool array
1580+
bool_result = np.array([quad_val]).astype(bool)[0]
1581+
py_bool = bool(quad_val)
1582+
1583+
# All non-zero values should be True
1584+
assert bool_result == True, f"QuadPrecision({val}) should be truthy, got {bool_result}"
1585+
assert py_bool == True, f"Python bool(QuadPrecision({val})) should be truthy, got {py_bool}"
1586+
1587+
1588+
@pytest.mark.parametrize("val", [
1589+
0.0, -0.0,
1590+
])
1591+
def test_bool_cast_zero_is_falsy(val):
1592+
"""Test that zero values correctly cast to False."""
1593+
quad_val = QuadPrecision(str(val))
1594+
1595+
# Cast to bool array
1596+
bool_result = np.array([quad_val]).astype(bool)[0]
1597+
py_bool = bool(quad_val)
1598+
1599+
# Zero values should be False
1600+
assert bool_result == False, f"QuadPrecision({val}) should be falsy, got {bool_result}"
1601+
assert py_bool == False, f"Python bool(QuadPrecision({val})) should be falsy, got {py_bool}"
1602+
1603+
def test_bool_cast_array():
1604+
"""Test boolean casting on arrays with mixed values."""
1605+
# Array with zeros and small non-zero values
1606+
values = ["0.0", "0.5", "-0.0", "1e-100", "1.0", "-1e-50"]
1607+
quad_arr = np.array([QuadPrecision(v) for v in values])
1608+
1609+
bool_arr = quad_arr.astype(bool)
1610+
1611+
# Expected: [False, True, False, True, True, True]
1612+
expected = [False, True, False, True, True, True]
1613+
1614+
for i, (got, exp) in enumerate(zip(bool_arr, expected)):
1615+
assert got == exp, f"Index {i} (value={values[i]}): expected {exp}, got {got}"
1616+
15571617

15581618
@pytest.mark.parametrize("op", ["amin", "amax", "nanmin", "nanmax"])
15591619
@pytest.mark.parametrize("a", ["3.0", "12.5", "100.0", "0.0", "-0.0", "inf", "-inf", "nan", "-nan"])

0 commit comments

Comments
 (0)