diff options
| author | Allan Haldane <allan.haldane@gmail.com> | 2017-10-28 19:46:53 -0400 |
|---|---|---|
| committer | Allan Haldane <allan.haldane@gmail.com> | 2017-11-04 14:53:55 -0400 |
| commit | 05c27efb6a7f0f3b689a1dcef1ef8c4e296f3643 (patch) | |
| tree | 6ea2547bd04d45c0e7c77874d0b180329181554d /numpy/core | |
| parent | 0b14f5085d7619a220c3530df719af365bd01b61 (diff) | |
| download | numpy-05c27efb6a7f0f3b689a1dcef1ef8c4e296f3643.tar.gz | |
ENH: Make numpy float scalars use dragon4 output
Diffstat (limited to 'numpy/core')
| -rw-r--r-- | numpy/core/src/multiarray/scalartypes.c.src | 295 | ||||
| -rw-r--r-- | numpy/core/src/multiarray/scalartypes.h | 3 |
2 files changed, 85 insertions, 213 deletions
diff --git a/numpy/core/src/multiarray/scalartypes.c.src b/numpy/core/src/multiarray/scalartypes.c.src index 87d29bf04..a208c2f73 100644 --- a/numpy/core/src/multiarray/scalartypes.c.src +++ b/numpy/core/src/multiarray/scalartypes.c.src @@ -26,6 +26,7 @@ #include "datetime_strings.h" #include "alloc.h" #include "npy_import.h" +#include "dragon4.h" #include <stdlib.h> @@ -429,146 +430,29 @@ gentype_format(PyObject *self, PyObject *args) #endif /**begin repeat - * #name = float, double, longdouble# - * #NAME = FLOAT, DOUBLE, LONGDOUBLE# - * #type = npy_float, npy_double, npy_longdouble# - * #suff = f, d, l# + * #name = half, float, double, longdouble# + * #NAME = HALF, FLOAT, DOUBLE, LONGDOUBLE# + * #type = npy_half, npy_float, npy_double, npy_longdouble# + * #suff = h, f, d, l# */ -#define _FMT1 "%%.%i" NPY_@NAME@_FMT -#define _FMT2 "%%+.%i" NPY_@NAME@_FMT - -NPY_NO_EXPORT void -format_@name@(char *buf, size_t buflen, @type@ val, unsigned int prec) +NPY_NO_EXPORT PyObject * +format_@name@(@type@ val, npy_bool scientific, + int precision, int sign, TrimMode trim, + int pad_left, int pad_right, int exp_digits) { - /* XXX: Find a correct size here for format string */ - char format[64], *res; - size_t i, cnt; - - PyOS_snprintf(format, sizeof(format), _FMT1, prec); - res = NumPyOS_ascii_format@suff@(buf, buflen, format, val, 0); - if (res == NULL) { - fprintf(stderr, "Error while formatting\n"); - return; - } - - /* If nothing but digits after sign, append ".0" */ - cnt = strlen(buf); - for (i = (buf[0] == '-') ? 1 : 0; i < cnt; ++i) { - if (!isdigit(Py_CHARMASK(buf[i]))) { - break; - } - } - if (i == cnt && buflen >= cnt + 3) { - strcpy(&buf[cnt],".0"); - } -} - -#undef _FMT1 -#undef _FMT2 - -/**end repeat**/ - -/**begin repeat - * #name = cfloat, cdouble, clongdouble# - * #NAME = FLOAT, DOUBLE, LONGDOUBLE# - * #type = npy_cfloat, npy_cdouble, npy_clongdouble# - * #suff = f, d, l# - */ - -#define _FMT1 "%%.%i" NPY_@NAME@_FMT -#define _FMT2 "%%+.%i" NPY_@NAME@_FMT - -static void -format_@name@(char *buf, size_t buflen, @type@ val, unsigned int prec) -{ - /* XXX: Find a correct size here for format string */ - char format[64]; - char *res; - - /* - * Ideally, we should handle this nan/inf stuff in NumpyOS_ascii_format* - */ - if (val.real == 0.0 && npy_signbit(val.real) == 0) { - PyOS_snprintf(format, sizeof(format), _FMT1, prec); - res = NumPyOS_ascii_format@suff@(buf, buflen - 1, format, val.imag, 0); - if (res == NULL) { - /* FIXME - * We need a better way to handle the error message - */ - fprintf(stderr, "Error while formatting\n"); - return; - } - if (!npy_isfinite(val.imag)) { - strncat(buf, "*", 1); - } - strncat(buf, "j", 1); + if (scientific) { + return Dragon4_Scientific_AnySize(&val, sizeof(@type@), 1, precision, + sign, trim, pad_left, exp_digits); } else { - char re[64], im[64]; - if (npy_isfinite(val.real)) { - PyOS_snprintf(format, sizeof(format), _FMT1, prec); - res = NumPyOS_ascii_format@suff@(re, sizeof(re), format, - val.real, 0); - if (res == NULL) { - /* FIXME - * We need a better way to handle the error message - */ - fprintf(stderr, "Error while formatting\n"); - return; - } - } - else { - if (npy_isnan(val.real)) { - strcpy(re, "nan"); - } - else if (val.real > 0){ - strcpy(re, "inf"); - } - else { - strcpy(re, "-inf"); - } - } - - - if (npy_isfinite(val.imag)) { - PyOS_snprintf(format, sizeof(format), _FMT2, prec); - res = NumPyOS_ascii_format@suff@(im, sizeof(im), format, - val.imag, 0); - if (res == NULL) { - fprintf(stderr, "Error while formatting\n"); - return; - } - } - else { - if (npy_isnan(val.imag)) { - strcpy(im, "+nan"); - } - else if (val.imag > 0){ - strcpy(im, "+inf"); - } - else { - strcpy(im, "-inf"); - } - if (!npy_isfinite(val.imag)) { - strncat(im, "*", 1); - } - } - PyOS_snprintf(buf, buflen, "(%s%sj)", re, im); + return Dragon4_Positional_AnySize(&val, sizeof(@type@), 1, precision, + sign, trim, pad_left, pad_right); } } -#undef _FMT1 -#undef _FMT2 - /**end repeat**/ -NPY_NO_EXPORT void -format_half(char *buf, size_t buflen, npy_half val, unsigned int prec) -{ - format_float(buf, buflen, npy_half_to_float(val), prec); -} - /* * over-ride repr and str of array-scalar strings and unicode to * remove NULL bytes and then call the corresponding functions @@ -828,21 +712,6 @@ timedeltatype_str(PyObject *self) return ret; } -/* The REPR values are finfo.precision + 2 */ -#define HALFPREC_REPR 5 -#define HALFPREC_STR 5 -#define FLOATPREC_REPR 8 -#define FLOATPREC_STR 6 -#define DOUBLEPREC_REPR 17 -#define DOUBLEPREC_STR 12 -#if NPY_SIZEOF_LONGDOUBLE == NPY_SIZEOF_DOUBLE -#define LONGDOUBLEPREC_REPR DOUBLEPREC_REPR -#define LONGDOUBLEPREC_STR DOUBLEPREC_STR -#else /* More than probably needed on Intel FP */ -#define LONGDOUBLEPREC_REPR 20 -#define LONGDOUBLEPREC_STR 12 -#endif - /* * float type str and repr * @@ -850,85 +719,100 @@ timedeltatype_str(PyObject *self) */ /**begin repeat - * #name = half, float, double, longdouble# - * #Name = Half, Float, Double, LongDouble# - * #NAME = HALF, FLOAT, DOUBLE, LONGDOUBLE# - * #hascomplex = 0, 1, 1, 1# + * #kind = str, repr# */ + /**begin repeat1 - * #kind = str, repr# - * #KIND = STR, REPR# + * #name = float, double, longdouble# + * #Name = Float, Double, LongDouble# + * #NAME = FLOAT, DOUBLE, LONGDOUBLE# */ -#define PREC @NAME@PREC_@KIND@ +static PyObject * +@name@type_@kind@_either(npy_@name@ val, TrimMode trim_pos, TrimMode trim_sci, + npy_bool sign) +{ + if (val < (npy_@name@)1.e16L) { + return format_@name@(val, 0, -1, sign, trim_pos, -1, -1, -1); + } + return format_@name@(val, 1, -1, sign, trim_sci, -1, -1, -1); +} static PyObject * @name@type_@kind@(PyObject *self) { - char buf[100]; - npy_@name@ val = ((Py@Name@ScalarObject *)self)->obval; - - format_@name@(buf, sizeof(buf), val, PREC); - return PyUString_FromString(buf); + return @name@type_@kind@_either(((Py@Name@ScalarObject *)self)->obval, + TrimMode_LeaveOneZero, TrimMode_DptZeros, 0); } -#if @hascomplex@ static PyObject * c@name@type_@kind@(PyObject *self) { - char buf[202]; + PyObject *rstr, *istr, *ret; npy_c@name@ val = ((PyC@Name@ScalarObject *)self)->obval; + TrimMode trim = TrimMode_DptZeros; + + if (val.real == 0.0 && npy_signbit(val.real) == 0) { + istr = @name@type_@kind@_either(val.imag, trim, trim, 0); + if (istr == NULL) { + return NULL; + } + PyUString_ConcatAndDel(&istr, PyUString_FromString("j")); + return istr; + } + + if (npy_isfinite(val.real)) { + rstr = @name@type_@kind@_either(val.real, trim, trim, 0); + if (rstr == NULL) { + return NULL; + } + } + else if (npy_isnan(val.real)) { + rstr = PyUString_FromString("nan"); + } + else if (val.real > 0){ + rstr = PyUString_FromString("inf"); + } + else { + rstr = PyUString_FromString("-inf"); + } + + if (npy_isfinite(val.imag)) { + istr = @name@type_@kind@_either(val.imag, trim, trim, 1); + if (istr == NULL) { + return NULL; + } + } + else if (npy_isnan(val.imag)) { + istr = PyUString_FromString("+nan"); + } + else if (val.imag > 0){ + istr = PyUString_FromString("+inf"); + } + else { + istr = PyUString_FromString("-inf"); + } - format_c@name@(buf, sizeof(buf), val, PREC); - return PyUString_FromString(buf); + ret = PyUString_FromString("("); + PyUString_ConcatAndDel(&ret, rstr); + PyUString_ConcatAndDel(&ret, istr); + PyUString_ConcatAndDel(&ret, PyUString_FromString("j)")); + return ret; } -#endif #undef PREC /**end repeat1**/ -/**end repeat**/ - -/* - * float type print (control print a, where a is a float type instance) - */ -/**begin repeat - * #name = half, float, double, longdouble# - * #Name = Half, Float, Double, LongDouble# - * #NAME = HALF, FLOAT, DOUBLE, LONGDOUBLE# - * #hascomplex = 0, 1, 1, 1# - */ - -static int -@name@type_print(PyObject *v, FILE *fp, int flags) -{ - char buf[100]; - npy_@name@ val = ((Py@Name@ScalarObject *)v)->obval; - - format_@name@(buf, sizeof(buf), val, - (flags & Py_PRINT_RAW) ? @NAME@PREC_STR : @NAME@PREC_REPR); - Py_BEGIN_ALLOW_THREADS - fputs(buf, fp); - Py_END_ALLOW_THREADS - return 0; -} -#if @hascomplex@ -static int -c@name@type_print(PyObject *v, FILE *fp, int flags) +static PyObject * +halftype_@kind@(PyObject *self) { - /* Size of buf: twice sizeof(real) + 2 (for the parenthesis) */ - char buf[202]; - npy_c@name@ val = ((PyC@Name@ScalarObject *)v)->obval; - - format_c@name@(buf, sizeof(buf), val, - (flags & Py_PRINT_RAW) ? @NAME@PREC_STR : @NAME@PREC_REPR); - Py_BEGIN_ALLOW_THREADS - fputs(buf, fp); - Py_END_ALLOW_THREADS - return 0; + npy_half val = ((PyHalfScalarObject *)self)->obval; + if (npy_half_to_double(val) < 1.e16) { + return format_half(val, 0, -1, 0, TrimMode_LeaveOneZero, -1, -1, -1); + } + return format_half(val, 1, -1, 0, TrimMode_DptZeros, -1, -1, -1); } -#endif /**end repeat**/ @@ -4227,15 +4111,6 @@ initialize_numeric_types(void) /**end repeat**/ - PyHalfArrType_Type.tp_print = halftype_print; - PyFloatArrType_Type.tp_print = floattype_print; - PyDoubleArrType_Type.tp_print = doubletype_print; - PyLongDoubleArrType_Type.tp_print = longdoubletype_print; - - PyCFloatArrType_Type.tp_print = cfloattype_print; - PyCDoubleArrType_Type.tp_print = cdoubletype_print; - PyCLongDoubleArrType_Type.tp_print = clongdoubletype_print; - /* * These need to be coded specially because getitem does not * return a normal Python type diff --git a/numpy/core/src/multiarray/scalartypes.h b/numpy/core/src/multiarray/scalartypes.h index b8d6cf83e..83b188128 100644 --- a/numpy/core/src/multiarray/scalartypes.h +++ b/numpy/core/src/multiarray/scalartypes.h @@ -19,9 +19,6 @@ initialize_casting_tables(void); NPY_NO_EXPORT void initialize_numeric_types(void); -NPY_NO_EXPORT void -format_longdouble(char *buf, size_t buflen, npy_longdouble val, unsigned int prec); - #if PY_VERSION_HEX >= 0x03000000 NPY_NO_EXPORT void gentype_struct_free(PyObject *ptr); |
