From ce2b9e06baf521781e3552c9d6b8b2174b66c13c Mon Sep 17 00:00:00 2001 From: Juniper Tyree <50025784+juntyr@users.noreply.github.com> Date: Wed, 20 Aug 2025 06:19:23 +0000 Subject: [PATCH 1/3] Add bits, precision, resolution constants --- quaddtype/numpy_quaddtype/__init__.py | 7 ++++++- quaddtype/tests/test_quaddtype.py | 7 ++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/quaddtype/numpy_quaddtype/__init__.py b/quaddtype/numpy_quaddtype/__init__.py index e4068ff6..1036ad03 100644 --- a/quaddtype/numpy_quaddtype/__init__.py +++ b/quaddtype/numpy_quaddtype/__init__.py @@ -13,11 +13,13 @@ 'SleefQuadPrecDType', 'LongDoubleQuadPrecDType', 'is_longdouble_128', # Constants 'pi', 'e', 'log2e', 'log10e', 'ln2', 'ln10', 'max_value', 'epsilon', - 'smallest_normal', 'smallest_subnormal', + 'smallest_normal', 'smallest_subnormal', 'bits', 'precision', 'resolution', # QuadBLAS related functions 'set_num_threads', 'get_num_threads', 'get_quadblas_version' ] +import numpy as np + def SleefQuadPrecision(value): return QuadPrecision(value, backend='sleef') @@ -40,3 +42,6 @@ def LongDoubleQuadPrecDType(): epsilon = get_sleef_constant("epsilon") smallest_normal = get_sleef_constant("smallest_normal") smallest_subnormal = get_sleef_constant("smallest_subnormal") +bits = SleefQuadPrecDType().itemsize * 8 +precision = int(-np.log10(epsilon)) +resolution = SleefQuadPrecision(10) ** (-precision) diff --git a/quaddtype/tests/test_quaddtype.py b/quaddtype/tests/test_quaddtype.py index 906c4417..1b4591cb 100644 --- a/quaddtype/tests/test_quaddtype.py +++ b/quaddtype/tests/test_quaddtype.py @@ -19,11 +19,16 @@ def test_math_constant(name, expected): assert np.float64(getattr(numpy_quaddtype, name)) == expected -@pytest.mark.parametrize("name", ["max_value", "epsilon", "smallest_normal", "smallest_subnormal"]) +@pytest.mark.parametrize("name", ["max_value", "epsilon", "smallest_normal", "smallest_subnormal", "resolution"]) def test_finfo_constant(name): assert isinstance(getattr(numpy_quaddtype, name), QuadPrecision) +@pytest.mark.parametrize("name,value", [("bits", 128), ("precision", 33)]) +def test_finfo_int_constant(name, value): + assert getattr(numpy_quaddtype, name) == value + + def test_basic_equality(): assert QuadPrecision("12") == QuadPrecision( "12.0") == QuadPrecision("12.00") From 8fe110f629d3671c29ff73d0c3bf6e27565b2fa8 Mon Sep 17 00:00:00 2001 From: Juniper Tyree <50025784+juntyr@users.noreply.github.com> Date: Sat, 23 Aug 2025 03:59:43 +0000 Subject: [PATCH 2/3] Move constant computation to C++ --- quaddtype/numpy_quaddtype/__init__.py | 8 +++----- quaddtype/numpy_quaddtype/src/quaddtype_main.c | 16 ++++++++++++++++ 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/quaddtype/numpy_quaddtype/__init__.py b/quaddtype/numpy_quaddtype/__init__.py index 1036ad03..abdc20e0 100644 --- a/quaddtype/numpy_quaddtype/__init__.py +++ b/quaddtype/numpy_quaddtype/__init__.py @@ -18,8 +18,6 @@ 'set_num_threads', 'get_num_threads', 'get_quadblas_version' ] -import numpy as np - def SleefQuadPrecision(value): return QuadPrecision(value, backend='sleef') @@ -42,6 +40,6 @@ def LongDoubleQuadPrecDType(): epsilon = get_sleef_constant("epsilon") smallest_normal = get_sleef_constant("smallest_normal") smallest_subnormal = get_sleef_constant("smallest_subnormal") -bits = SleefQuadPrecDType().itemsize * 8 -precision = int(-np.log10(epsilon)) -resolution = SleefQuadPrecision(10) ** (-precision) +bits = get_sleef_constant("bits") +precision = get_sleef_constant("precision") +resolution = get_sleef_constant("resolution") diff --git a/quaddtype/numpy_quaddtype/src/quaddtype_main.c b/quaddtype/numpy_quaddtype/src/quaddtype_main.c index 3825dfc6..9a883876 100644 --- a/quaddtype/numpy_quaddtype/src/quaddtype_main.c +++ b/quaddtype/numpy_quaddtype/src/quaddtype_main.c @@ -73,6 +73,22 @@ get_sleef_constant(PyObject *self, PyObject *args) else if (strcmp(constant_name, "smallest_subnormal") == 0) { result->value.sleef_value = SLEEF_QUAD_DENORM_MIN; } + else if (strcmp(constant_name, "bits") == 0) { + Py_DECREF(result); + return PyLong_FromLong(sizeof(Sleef_quad) * CHAR_BIT); + } + else if (strcmp(constant_name, "precision") == 0) { + Py_DECREF(result); + // precision = int(-log10(epsilon)) + auto precision = Sleef_cast_to_int64q1(Sleef_negq1(Sleef_log10q1_u10(SLEEF_QUAD_EPSILON))); + return PyLong_FromLong(precision); + } + else if (strcmp(constant_name, "resolution") == 0) { + // precision = int(-log10(epsilon)) + auto precision = Sleef_cast_to_int64q1(Sleef_negq1(Sleef_log10q1_u10(SLEEF_QUAD_EPSILON))); + // resolution = 10 ** (-precision) + result->value.sleef_value = Sleef_powq1_u10(Sleef_cast_from_int64q1(10), Sleef_cast_from_int64q1(-precision)); + } else { PyErr_SetString(PyExc_ValueError, "Unknown constant name"); Py_DECREF(result); From fe476c2ea755651be1e203df2557c9a2715ef27c Mon Sep 17 00:00:00 2001 From: Juniper Tyree <50025784+juntyr@users.noreply.github.com> Date: Sat, 23 Aug 2025 04:04:00 +0000 Subject: [PATCH 3/3] Use int64_t for sleef precision --- quaddtype/numpy_quaddtype/src/quaddtype_main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/quaddtype/numpy_quaddtype/src/quaddtype_main.c b/quaddtype/numpy_quaddtype/src/quaddtype_main.c index 9a883876..39f3da8a 100644 --- a/quaddtype/numpy_quaddtype/src/quaddtype_main.c +++ b/quaddtype/numpy_quaddtype/src/quaddtype_main.c @@ -80,12 +80,12 @@ get_sleef_constant(PyObject *self, PyObject *args) else if (strcmp(constant_name, "precision") == 0) { Py_DECREF(result); // precision = int(-log10(epsilon)) - auto precision = Sleef_cast_to_int64q1(Sleef_negq1(Sleef_log10q1_u10(SLEEF_QUAD_EPSILON))); + int64_t precision = Sleef_cast_to_int64q1(Sleef_negq1(Sleef_log10q1_u10(SLEEF_QUAD_EPSILON))); return PyLong_FromLong(precision); } else if (strcmp(constant_name, "resolution") == 0) { // precision = int(-log10(epsilon)) - auto precision = Sleef_cast_to_int64q1(Sleef_negq1(Sleef_log10q1_u10(SLEEF_QUAD_EPSILON))); + int64_t precision = Sleef_cast_to_int64q1(Sleef_negq1(Sleef_log10q1_u10(SLEEF_QUAD_EPSILON))); // resolution = 10 ** (-precision) result->value.sleef_value = Sleef_powq1_u10(Sleef_cast_from_int64q1(10), Sleef_cast_from_int64q1(-precision)); }