summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--numpy/core/src/multiarray/convert_datatype.c2
-rw-r--r--numpy/core/src/multiarray/scalartypes.c.src12
-rw-r--r--numpy/core/tests/test_strings.py14
3 files changed, 24 insertions, 4 deletions
diff --git a/numpy/core/src/multiarray/convert_datatype.c b/numpy/core/src/multiarray/convert_datatype.c
index 3973fc795..14341c103 100644
--- a/numpy/core/src/multiarray/convert_datatype.c
+++ b/numpy/core/src/multiarray/convert_datatype.c
@@ -2880,7 +2880,7 @@ add_other_to_and_from_string_cast(
.name = "legacy_cast_to_string",
.nin = 1,
.nout = 1,
- .flags = NPY_METH_REQUIRES_PYAPI,
+ .flags = NPY_METH_REQUIRES_PYAPI | NPY_METH_NO_FLOATINGPOINT_ERRORS,
.dtypes = dtypes,
.slots = slots,
};
diff --git a/numpy/core/src/multiarray/scalartypes.c.src b/numpy/core/src/multiarray/scalartypes.c.src
index bb5d36ba1..57336589e 100644
--- a/numpy/core/src/multiarray/scalartypes.c.src
+++ b/numpy/core/src/multiarray/scalartypes.c.src
@@ -896,15 +896,21 @@ static PyObject *
@name@type_@kind@_either(npy_@name@ val, TrimMode trim_pos, TrimMode trim_sci,
npy_bool sign)
{
- npy_@name@ absval;
if (npy_legacy_print_mode <= 113) {
return legacy_@name@_format@kind@(val);
}
- absval = val < 0 ? -val : val;
+ int use_positional;
+ if (npy_isnan(val) || val == 0) {
+ use_positional = 1;
+ }
+ else {
+ npy_@name@ absval = val < 0 ? -val : val;
+ use_positional = absval < 1.e16L && absval >= 1.e-4L;
+ }
- if (absval == 0 || (absval < 1.e16L && absval >= 1.e-4L) ) {
+ if (use_positional) {
return format_@name@(val, 0, -1, sign, trim_pos, -1, -1, -1);
}
return format_@name@(val, 1, -1, sign, trim_sci, -1, -1, -1);
diff --git a/numpy/core/tests/test_strings.py b/numpy/core/tests/test_strings.py
index 2b87ed654..27ca3b303 100644
--- a/numpy/core/tests/test_strings.py
+++ b/numpy/core/tests/test_strings.py
@@ -83,3 +83,17 @@ def test_string_comparisons_empty(op, ufunc, sym, dtypes):
assert_array_equal(op(arr, arr2), expected)
assert_array_equal(ufunc(arr, arr2), expected)
assert_array_equal(np.compare_chararrays(arr, arr2, sym, False), expected)
+
+
+@pytest.mark.parametrize("str_dt", ["S", "U"])
+@pytest.mark.parametrize("float_dt", np.typecodes["AllFloat"])
+def test_float_to_string_cast(str_dt, float_dt):
+ float_dt = np.dtype(float_dt)
+ fi = np.finfo(float_dt)
+ arr = np.array([np.nan, np.inf, -np.inf, fi.max, fi.tiny], dtype=float_dt)
+ expected = ["nan", "inf", "-inf", repr(fi.max), repr(fi.tiny)]
+ if float_dt.kind == 'c':
+ expected = [f"({r}+0j)" for r in expected]
+
+ res = arr.astype(str_dt)
+ assert_array_equal(res, np.array(expected, dtype=str_dt))