summaryrefslogtreecommitdiff
path: root/numpy/core
diff options
context:
space:
mode:
authorAllan Haldane <allan.haldane@gmail.com>2017-10-28 19:46:53 -0400
committerAllan Haldane <allan.haldane@gmail.com>2017-11-04 14:53:55 -0400
commit05c27efb6a7f0f3b689a1dcef1ef8c4e296f3643 (patch)
tree6ea2547bd04d45c0e7c77874d0b180329181554d /numpy/core
parent0b14f5085d7619a220c3530df719af365bd01b61 (diff)
downloadnumpy-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.src295
-rw-r--r--numpy/core/src/multiarray/scalartypes.h3
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);