diff options
author | Eric Wieser <wieser.eric@gmail.com> | 2017-04-06 22:39:49 +0100 |
---|---|---|
committer | Eric Wieser <wieser.eric@gmail.com> | 2017-04-06 22:56:04 +0100 |
commit | a770387f29d4847a1b0b3b304b78e646a00a9b51 (patch) | |
tree | a227f11e52fe6e183222e041b2f76d4c916ad197 /numpy/core | |
parent | 54487a8668c2fd1aa6e63be1f60ca891720db6d0 (diff) | |
download | numpy-a770387f29d4847a1b0b3b304b78e646a00a9b51.tar.gz |
BUG: Don't call float when constructing longdouble arrays
This addresses some of #8902, preventing precision loss
Diffstat (limited to 'numpy/core')
-rw-r--r-- | numpy/core/src/multiarray/arraytypes.c.src | 14 | ||||
-rw-r--r-- | numpy/core/tests/test_multiarray.py | 29 |
2 files changed, 43 insertions, 0 deletions
diff --git a/numpy/core/src/multiarray/arraytypes.c.src b/numpy/core/src/multiarray/arraytypes.c.src index b43f267f3..1fa54d325 100644 --- a/numpy/core/src/multiarray/arraytypes.c.src +++ b/numpy/core/src/multiarray/arraytypes.c.src @@ -374,6 +374,20 @@ LONGDOUBLE_setitem(PyObject *op, void *ov, void *vap) /* ensure alignment */ npy_longdouble temp; + /* Handle case of assigning from an array scalar */ + if (PyArray_Check(op) && PyArray_NDIM((PyArrayObject *)op) == 0) { + PyObject *temp = PyArray_ToScalar(PyArray_BYTES((PyArrayObject *)op), + (PyArrayObject *)op); + if (temp == NULL) { + return -1; + } + else { + int res = LONGDOUBLE_setitem(temp, ov, ap); + Py_DECREF(temp); + return res; + } + } + if (PyArray_IsScalar(op, LongDouble)) { temp = ((PyLongDoubleScalarObject *)op)->obval; } diff --git a/numpy/core/tests/test_multiarray.py b/numpy/core/tests/test_multiarray.py index f7cb58bc1..373f151b2 100644 --- a/numpy/core/tests/test_multiarray.py +++ b/numpy/core/tests/test_multiarray.py @@ -404,6 +404,35 @@ class TestAssignment(TestCase): # this would crash for the same reason np.array([np.array(u'\xe5\xe4\xf6')]) + def test_longdouble_assignment(self): + # only relevant if longdouble is larger than float + # we're looking for loss of precision + + # gh-8902 + tinyb = np.nextafter(np.longdouble(0), 1) + tinya = np.nextafter(np.longdouble(0), -1) + tiny1d = np.array([tinya]) + assert_equal(tiny1d[0], tinya) + + # scalar = scalar + tiny1d[0] = tinyb + assert_equal(tiny1d[0], tinyb) + + # 0d = scalar + tiny1d[0, ...] = tinya + assert_equal(tiny1d[0], tinya) + + # 0d = 0d + tiny1d[0, ...] = tinyb[...] + assert_equal(tiny1d[0], tinyb) + + # scalar = 0d + tiny1d[0] = tinyb[...] + assert_equal(tiny1d[0], tinyb) + + arr = np.array([np.array(tinya)]) + assert_equal(arr[0], tinya) + class TestDtypedescr(TestCase): def test_construction(self): |