diff options
Diffstat (limited to 'numpy')
-rw-r--r-- | numpy/add_newdocs.py | 31 | ||||
-rw-r--r-- | numpy/core/src/multiarray/_multiarray_tests.c.src | 63 |
2 files changed, 93 insertions, 1 deletions
diff --git a/numpy/add_newdocs.py b/numpy/add_newdocs.py index fc2130096..9372b3431 100644 --- a/numpy/add_newdocs.py +++ b/numpy/add_newdocs.py @@ -5607,6 +5607,37 @@ add_newdoc('numpy.core.multiarray', 'unpackbits', """) +add_newdoc('numpy.core._multiarray_tests', 'format_float_OSprintf_g', + """ + format_float_OSprintf_g(val, precision) + + Print a floating point scalar using the system's printf function, + equivalent to: + + printf("%.*g", precision, val); + + for half/float/double, or replacing 'g' by 'Lg' for longdouble. This + method is designed to help cross-validate the format_float_* methods. + + Parameters + ---------- + val : python float or numpy floating scalar + Value to format. + + precision : non-negative integer, optional + Precision given to printf. + + Returns + ------- + rep : string + The string representation of the floating point value + + See Also + -------- + format_float_scientific + format_float_positional + """) + ############################################################################## # diff --git a/numpy/core/src/multiarray/_multiarray_tests.c.src b/numpy/core/src/multiarray/_multiarray_tests.c.src index 0299f1a1b..cba96a4c2 100644 --- a/numpy/core/src/multiarray/_multiarray_tests.c.src +++ b/numpy/core/src/multiarray/_multiarray_tests.c.src @@ -3,7 +3,9 @@ #include <Python.h> #define _NPY_NO_DEPRECATIONS /* for NPY_CHAR */ #include "numpy/arrayobject.h" +#include "numpy/arrayscalars.h" #include "numpy/npy_math.h" +#include "numpy/halffloat.h" #include "mem_overlap.h" #include "npy_extint128.h" #include "common.h" @@ -1828,6 +1830,63 @@ call_npy_@name@@suffix@(PyObject *NPY_UNUSED(self), PyObject *args) /**end repeat**/ +/* + * For development/testing purposes, it's convenient to have access to the + * system printf for floats. This is a very simple printf interface. + */ +PyObject * +PrintFloat_Printf_g(PyObject *obj, int precision) +{ + char str[1024]; + + if (PyArray_IsScalar(obj, Half)) { + npy_half x = ((PyHalfScalarObject *)obj)->obval; + PyOS_snprintf(str, sizeof(str), "%.*g", precision, + npy_half_to_double(x)); + } + else if (PyArray_IsScalar(obj, Float)) { + npy_float x = ((PyFloatScalarObject *)obj)->obval; + PyOS_snprintf(str, sizeof(str), "%.*g", precision, x); + } + else if (PyArray_IsScalar(obj, Double)) { + npy_double x = ((PyDoubleScalarObject *)obj)->obval; + PyOS_snprintf(str, sizeof(str), "%.*g", precision, x); + /* would be better to use lg, but not available in C90 */ + } + else if (PyArray_IsScalar(obj, LongDouble)) { + npy_longdouble x = ((PyLongDoubleScalarObject *)obj)->obval; + PyOS_snprintf(str, sizeof(str), "%.*Lg", precision, x); + } + else{ + double val = PyFloat_AsDouble(obj); + if (error_converting(val)) { + return NULL; + } + PyOS_snprintf(str, sizeof(str), "%.*g", precision, val); + } + + return PyUString_FromString(str); +} + + +static PyObject * +printf_float_g(PyObject *NPY_UNUSED(dummy), PyObject *args, PyObject *kwds) +{ + PyObject *obj; + int precision; + + if (!PyArg_ParseTuple(args,"Oi:format_float_OSprintf_g", &obj, + &precision)) { + return NULL; + } + + if (precision < 0) { + PyErr_SetString(PyExc_TypeError, "precision must be non-negative"); + return NULL; + } + + return PrintFloat_Printf_g(obj, precision); +} static PyMethodDef Multiarray_TestsMethods[] = { {"IsPythonScalar", @@ -1967,7 +2026,9 @@ static PyMethodDef Multiarray_TestsMethods[] = { /**end repeat1**/ /**end repeat**/ - + {"format_float_OSprintf_g", + (PyCFunction)printf_float_g, + METH_VARARGS , NULL}, {NULL, NULL, 0, NULL} /* Sentinel */ }; |