summaryrefslogtreecommitdiff
path: root/numpy/core
diff options
context:
space:
mode:
authorEric Wieser <wieser.eric@gmail.com>2017-04-06 22:39:49 +0100
committerEric Wieser <wieser.eric@gmail.com>2017-04-06 22:56:04 +0100
commita770387f29d4847a1b0b3b304b78e646a00a9b51 (patch)
treea227f11e52fe6e183222e041b2f76d4c916ad197 /numpy/core
parent54487a8668c2fd1aa6e63be1f60ca891720db6d0 (diff)
downloadnumpy-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.src14
-rw-r--r--numpy/core/tests/test_multiarray.py29
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):