Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions quaddtype/numpy_quaddtype/src/scalar.c
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,42 @@ QuadPrecision_dealloc(QuadPrecisionObject *self)
Py_TYPE(self)->tp_free((PyObject *)self);
}

static int
QuadPrecision_getbuffer(QuadPrecisionObject *self, Py_buffer *view, int flags)
{
if (view == NULL) {
PyErr_SetString(PyExc_ValueError, "NULL view in getbuffer");
return -1;
}

if ((flags & PyBUF_WRITABLE) == PyBUF_WRITABLE) {
PyErr_SetString(PyExc_BufferError, "QuadPrecision scalar is not writable");
return -1;
}

size_t elem_size = (self->backend == BACKEND_SLEEF) ? sizeof(Sleef_quad) : sizeof(long double);

view->obj = (PyObject *)self;
Py_INCREF(self);
view->buf = &self->value;
view->len = elem_size;
view->readonly = 1;
view->itemsize = elem_size;
view->format = NULL; // No format string for now
view->ndim = 0;
view->shape = NULL;
view->strides = NULL;
view->suboffsets = NULL;
view->internal = NULL;

return 0;
}

static PyBufferProcs QuadPrecision_as_buffer = {
.bf_getbuffer = (getbufferproc)QuadPrecision_getbuffer,
.bf_releasebuffer = NULL,
};

static PyObject *
QuadPrecision_get_real(QuadPrecisionObject *self, void *closure)
{
Expand Down Expand Up @@ -362,6 +398,7 @@ PyTypeObject QuadPrecision_Type = {
.tp_repr = (reprfunc)QuadPrecision_repr_dragon4,
.tp_str = (reprfunc)QuadPrecision_str_dragon4,
.tp_as_number = &quad_as_scalar,
.tp_as_buffer = &QuadPrecision_as_buffer,
.tp_richcompare = (richcmpfunc)quad_richcompare,
.tp_getset = QuadPrecision_getset,
};
Expand Down
9 changes: 8 additions & 1 deletion quaddtype/tests/test_quaddtype.py
Original file line number Diff line number Diff line change
Expand Up @@ -3088,4 +3088,11 @@ def test_frexp_very_small(self):
# Verify reconstruction using ldexp (preserves full quad precision)
reconstructed = np.ldexp(quad_m, int(quad_e))
assert reconstructed == quad_x, \
f"Reconstruction failed for small value: {reconstructed} != {quad_x}"
f"Reconstruction failed for small value: {reconstructed} != {quad_x}"
# testng buffer
def test_buffer():
a = QuadPrecision(1.0)
buff = a.data

reconstructed = np.frombuffer(buff, dtype=QuadPrecDType())[0]
assert reconstructed == a, "Buffer reconstruction failed"