From 197656e563c9841a17da70ff1175104f73fe4093 Mon Sep 17 00:00:00 2001 From: SwayamInSync Date: Fri, 16 Jan 2026 16:25:46 +0000 Subject: [PATCH] quadprec_nonzero --- src/csrc/dtype.c | 20 ++++++++++++++++++++ tests/test_quaddtype.py | 24 ++++++++++++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/src/csrc/dtype.c b/src/csrc/dtype.c index 910b245..08c0830 100644 --- a/src/csrc/dtype.c +++ b/src/csrc/dtype.c @@ -389,6 +389,25 @@ quadprec_fromstr(char *s, void *dptr, char **endptr, PyArray_Descr *descr_generi return 0; } +static npy_bool +quadprec_nonzero(void *data, void *arr) +{ + PyArrayObject *arr_obj = (PyArrayObject *)arr; + QuadPrecDTypeObject *descr = (QuadPrecDTypeObject *)PyArray_DESCR(arr_obj); + QuadBackendType backend = descr->backend; + + if (backend == BACKEND_SLEEF) { + Sleef_quad val; + memcpy(&val, data, sizeof(Sleef_quad)); + return !Sleef_icmpeqq1(val, QUAD_PRECISION_ZERO); + } + else { + long double val; + memcpy(&val, data, sizeof(long double)); + return val != 0.0L; + } +} + static PyType_Slot QuadPrecDType_Slots[] = { {NPY_DT_ensure_canonical, &ensure_canonical}, {NPY_DT_common_instance, &common_instance}, @@ -398,6 +417,7 @@ static PyType_Slot QuadPrecDType_Slots[] = { {NPY_DT_getitem, &quadprec_getitem}, {NPY_DT_default_descr, &quadprec_default_descr}, {NPY_DT_get_constant, &quadprec_get_constant}, + {NPY_DT_PyArray_ArrFuncs_nonzero, &quadprec_nonzero}, {NPY_DT_PyArray_ArrFuncs_fill, &quadprec_fill}, {NPY_DT_PyArray_ArrFuncs_scanfunc, &quadprec_scanfunc}, {NPY_DT_PyArray_ArrFuncs_fromstr, &quadprec_fromstr}, diff --git a/tests/test_quaddtype.py b/tests/test_quaddtype.py index 6d98b79..ae8be9b 100644 --- a/tests/test_quaddtype.py +++ b/tests/test_quaddtype.py @@ -1531,6 +1531,30 @@ def test_unary_logical_not(x): assert isinstance(quad_result, (bool, np.bool_)), f"Result should be bool, got {type(quad_result)}" +@pytest.mark.parametrize("val,expected", [ + ("1.0", True), + ("0.5", True), + ("1e-100", True), + ("-1.0", True), + ("0.0", False), + ("-0.0", False), +]) +def test_bool_0d_array(val, expected): + """ + Test boolean conversion on 0-d QuadPrecision arrays. + + This tests that bool(np.array(QuadPrecision(x))) works correctly + and doesn't segfault due to missing dtype nonzero function. + """ + quad_scalar = QuadPrecision(val) + arr_0d = np.array(quad_scalar) + # Ensure it's actually a 0-d array + assert arr_0d.ndim == 0, f"Expected 0-d array, got {arr_0d.ndim}-d" + + # This should not segfault + result = bool(arr_0d) + assert result == expected, f"bool(np.array(QuadPrecision({val}))) should be {expected}, got {result}" + @pytest.mark.parametrize("op", ["amin", "amax", "nanmin", "nanmax"]) @pytest.mark.parametrize("a", ["3.0", "12.5", "100.0", "0.0", "-0.0", "inf", "-inf", "nan", "-nan"]) @pytest.mark.parametrize("b", ["3.0", "12.5", "100.0", "0.0", "-0.0", "inf", "-inf", "nan", "-nan"])