Skip to content

Commit 22982a4

Browse files
committed
adding dragon4
1 parent 01e9b7e commit 22982a4

File tree

7 files changed

+2201
-7
lines changed

7 files changed

+2201
-7
lines changed

quaddtype/numpy_quaddtype/src/dragon4.c

+2,057
Large diffs are not rendered by default.
+70
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
#ifndef _QUADDTYPE_DRAGON4_H
2+
#define _QUADDTYPE_DRAGON4_H
3+
4+
#ifdef __cplusplus
5+
extern "C" {
6+
#endif
7+
8+
#include <Python.h>
9+
#include "numpy/arrayobject.h"
10+
#include <sleef.h>
11+
#include "quad_common.h"
12+
13+
typedef enum DigitMode
14+
{
15+
/* Round digits to print shortest uniquely identifiable number. */
16+
DigitMode_Unique,
17+
/* Output the digits of the number as if with infinite precision */
18+
DigitMode_Exact,
19+
} DigitMode;
20+
21+
typedef enum CutoffMode
22+
{
23+
/* up to cutoffNumber significant digits */
24+
CutoffMode_TotalLength,
25+
/* up to cutoffNumber significant digits past the decimal point */
26+
CutoffMode_FractionLength,
27+
} CutoffMode;
28+
29+
typedef enum TrimMode
30+
{
31+
TrimMode_None, /* don't trim zeros, always leave a decimal point */
32+
TrimMode_LeaveOneZero, /* trim all but the zero before the decimal point */
33+
TrimMode_Zeros, /* trim all trailing zeros, leave decimal point */
34+
TrimMode_DptZeros, /* trim trailing zeros & trailing decimal point */
35+
} TrimMode;
36+
37+
typedef struct {
38+
int scientific;
39+
DigitMode digit_mode;
40+
CutoffMode cutoff_mode;
41+
int precision;
42+
int min_digits;
43+
int sign;
44+
TrimMode trim_mode;
45+
int digits_left;
46+
int digits_right;
47+
int exp_digits;
48+
} Dragon4_Options;
49+
50+
PyObject *Dragon4_Positional_QuadDType(Sleef_quad *val, DigitMode digit_mode,
51+
CutoffMode cutoff_mode, int precision, int min_digits,
52+
int sign, TrimMode trim, int pad_left, int pad_right);
53+
54+
PyObject *Dragon4_Scientific_QuadDType(Sleef_quad *val, DigitMode digit_mode,
55+
int precision, int min_digits, int sign, TrimMode trim,
56+
int pad_left, int exp_digits);
57+
58+
PyObject *Dragon4_Positional(PyObject *obj, DigitMode digit_mode,
59+
CutoffMode cutoff_mode, int precision, int min_digits,
60+
int sign, TrimMode trim, int pad_left, int pad_right);
61+
62+
PyObject *Dragon4_Scientific(PyObject *obj, DigitMode digit_mode, int precision,
63+
int min_digits, int sign, TrimMode trim, int pad_left,
64+
int exp_digits);
65+
66+
#ifdef __cplusplus
67+
}
68+
#endif
69+
70+
#endif /* _QUADDTYPE_DRAGON4_H */

quaddtype/numpy_quaddtype/src/dtype.c

+11-1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include "scalar.h"
1616
#include "casts.h"
1717
#include "dtype.h"
18+
#include "dragon4.h"
1819

1920
static inline int
2021
quad_load(void *x, char *data_ptr, QuadBackendType backend)
@@ -212,13 +213,22 @@ QuadPrecDType_repr(QuadPrecDTypeObject *self)
212213
return PyUnicode_FromFormat("QuadPrecDType(backend='%s')", backend_str);
213214
}
214215

216+
static PyObject *
217+
QuadPrecDType_str(QuadPrecDTypeObject *self)
218+
{
219+
const char *backend_str = (self->backend == BACKEND_SLEEF) ? "sleef" : "longdouble";
220+
return PyUnicode_FromFormat("QuadPrecDType(backend='%s')", backend_str);
221+
}
222+
223+
224+
215225
PyArray_DTypeMeta QuadPrecDType = {
216226
{{
217227
PyVarObject_HEAD_INIT(NULL, 0).tp_name = "numpy_quaddtype.QuadPrecDType",
218228
.tp_basicsize = sizeof(QuadPrecDTypeObject),
219229
.tp_new = QuadPrecDType_new,
220230
.tp_repr = (reprfunc)QuadPrecDType_repr,
221-
.tp_str = (reprfunc)QuadPrecDType_repr,
231+
.tp_str = (reprfunc)QuadPrecDType_str,
222232
}},
223233
};
224234

quaddtype/numpy_quaddtype/src/quaddtype_main.c

+1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include "quad_common.h"
1616
#include "float.h"
1717

18+
1819
static PyObject* py_is_longdouble_128(PyObject* self, PyObject* args) {
1920
if(sizeof(long double) == 16 &&
2021
LDBL_MANT_DIG == 113 &&

quaddtype/numpy_quaddtype/src/scalar.c

+59-2
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
#include "scalar.h"
1515
#include "scalar_ops.h"
16+
#include "dragon4.h"
1617

1718
QuadPrecisionObject *
1819
QuadPrecision_raw_new(QuadBackendType backend)
@@ -128,6 +129,29 @@ QuadPrecision_new(PyTypeObject *cls, PyObject *args, PyObject *kwargs)
128129
return (PyObject *)QuadPrecision_from_object(value, backend);
129130
}
130131

132+
static PyObject *
133+
QuadPrecision_str_dragon4(QuadPrecisionObject *self)
134+
{
135+
Dragon4_Options opt = {
136+
.scientific = 0,
137+
.digit_mode = DigitMode_Unique,
138+
.cutoff_mode = CutoffMode_TotalLength,
139+
.precision = SLEEF_QUAD_DIG,
140+
.sign = 1,
141+
.trim_mode = TrimMode_LeaveOneZero,
142+
.digits_left = 1,
143+
.digits_right = SLEEF_QUAD_DIG
144+
};
145+
146+
if (self->backend == BACKEND_SLEEF) {
147+
return Dragon4_Positional_QuadDType(&self->value.sleef_value, opt.digit_mode, opt.cutoff_mode, opt.precision, opt.min_digits, opt.sign, opt.trim_mode, opt.digits_left, opt.digits_right);
148+
}
149+
else {
150+
Sleef_quad sleef_val = Sleef_cast_from_doubleq1(self->value.longdouble_value);
151+
return Dragon4_Positional_QuadDType(&sleef_val, opt.digit_mode, opt.cutoff_mode, opt.precision, opt.min_digits, opt.sign, opt.trim_mode, opt.digits_left, opt.digits_right);
152+
}
153+
}
154+
131155
static PyObject *
132156
QuadPrecision_str(QuadPrecisionObject *self)
133157
{
@@ -154,6 +178,39 @@ QuadPrecision_repr(QuadPrecisionObject *self)
154178
return res;
155179
}
156180

181+
static PyObject *
182+
QuadPrecision_repr_dragon4(QuadPrecisionObject *self)
183+
{
184+
Dragon4_Options opt = {
185+
.scientific = 1,
186+
.digit_mode = DigitMode_Unique,
187+
.cutoff_mode = CutoffMode_TotalLength,
188+
.precision = SLEEF_QUAD_DIG,
189+
.sign = 1,
190+
.trim_mode = TrimMode_LeaveOneZero,
191+
.digits_left = 1,
192+
.exp_digits = 3
193+
};
194+
195+
PyObject *str;
196+
if (self->backend == BACKEND_SLEEF) {
197+
str = Dragon4_Scientific_QuadDType(&self->value.sleef_value, opt.digit_mode, opt.precision, opt.min_digits, opt.sign, opt.trim_mode, opt.digits_left, opt.exp_digits);
198+
}
199+
else {
200+
Sleef_quad sleef_val = Sleef_cast_from_doubleq1(self->value.longdouble_value);
201+
str = Dragon4_Scientific_QuadDType(&sleef_val, opt.digit_mode, opt.precision, opt.min_digits, opt.sign, opt.trim_mode, opt.digits_left, opt.exp_digits);
202+
}
203+
204+
if (str == NULL) {
205+
return NULL;
206+
}
207+
208+
const char *backend_str = (self->backend == BACKEND_SLEEF) ? "sleef" : "longdouble";
209+
PyObject *res = PyUnicode_FromFormat("QuadPrecision('%S', backend='%s')", str, backend_str);
210+
Py_DECREF(str);
211+
return res;
212+
}
213+
157214
static void
158215
QuadPrecision_dealloc(QuadPrecisionObject *self)
159216
{
@@ -166,8 +223,8 @@ PyTypeObject QuadPrecision_Type = {
166223
.tp_itemsize = 0,
167224
.tp_new = QuadPrecision_new,
168225
.tp_dealloc = (destructor)QuadPrecision_dealloc,
169-
.tp_repr = (reprfunc)QuadPrecision_repr,
170-
.tp_str = (reprfunc)QuadPrecision_str,
226+
.tp_repr = (reprfunc)QuadPrecision_repr_dragon4,
227+
.tp_str = (reprfunc)QuadPrecision_str_dragon4,
171228
.tp_as_number = &quad_as_scalar,
172229
.tp_richcompare = (richcmpfunc)quad_richcompare
173230

quaddtype/numpy_quaddtype/src/scalar.h

+3
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@ QuadPrecision_from_object(PyObject *value, QuadBackendType backend);
3131
int
3232
init_quadprecision_scalar(void);
3333

34+
#define PyArray_IsScalar(obj, QuadPrecDType) PyObject_TypeCheck(obj, &QuadPrecision_Type)
35+
#define PyArrayScalar_VAL(obj, QuadPrecDType) (((QuadPrecisionObject *)obj)->value)
36+
3437
#ifdef __cplusplus
3538
}
3639
#endif

quaddtype/numpy_quaddtype/src/umath.cpp

-4
Original file line numberDiff line numberDiff line change
@@ -232,9 +232,6 @@ quad_binary_op_resolve_descriptors(PyObject *self, PyArray_DTypeMeta *const dtyp
232232
QuadPrecDTypeObject *descr_in2 = (QuadPrecDTypeObject *)given_descrs[1];
233233
QuadBackendType target_backend;
234234

235-
const char *s1 = (descr_in1->backend == BACKEND_SLEEF) ? "SLEEF" : "LONGDOUBLE";
236-
const char *s2 = (descr_in2->backend == BACKEND_SLEEF) ? "SLEEF" : "LONGDOUBLE";
237-
238235
// Determine target backend and if casting is needed
239236
NPY_CASTING casting = NPY_NO_CASTING;
240237
if (descr_in1->backend != descr_in2->backend) {
@@ -323,7 +320,6 @@ quad_ufunc_promoter(PyUFuncObject *ufunc, PyArray_DTypeMeta *op_dtypes[],
323320
int nargs = ufunc->nargs;
324321
PyArray_DTypeMeta *common = NULL;
325322
bool has_quad = false;
326-
QuadBackendType backend = BACKEND_INVALID; // Initialize to an invalid state
327323

328324
// Handle the special case for reductions
329325
if (op_dtypes[0] == NULL) {

0 commit comments

Comments
 (0)