Blob Blame History Raw
diff --git a/h5py/h5t.pyx b/h5py/h5t.pyx
index 7d1d7a1..30746f9 100644
--- a/h5py/h5t.pyx
+++ b/h5py/h5t.pyx
@@ -231,6 +231,14 @@ IEEE_F128LE = IEEE_F128BE.copy()
 IEEE_F128LE.set_order(H5T_ORDER_LE)
 IEEE_F128LE.lock()
 
+LDOUBLE_LE = NATIVE_LDOUBLE.copy()
+LDOUBLE_LE.set_order(H5T_ORDER_LE)
+LDOUBLE_LE.lock()
+
+LDOUBLE_BE = NATIVE_LDOUBLE.copy()
+LDOUBLE_BE.set_order(H5T_ORDER_BE)
+LDOUBLE_BE.lock()
+
 # Custom Python object pointer type
 cdef hid_t H5PY_OBJ = H5Tcreate(H5T_OPAQUE, sizeof(PyObject*))
 H5Tset_tag(H5PY_OBJ, "PYTHON:OBJECT")
@@ -294,6 +302,29 @@ available_ftypes = _DeprecatedMapping(available_ftypes,
     "h5py. See https://github.com/h5py/h5py/pull/926 for details.")
 )
 
+
+cdef (int, int, int) _correct_float_info(ftype_, finfo):
+    nmant = finfo.nmant
+    maxexp = finfo.maxexp
+    minexp = finfo.minexp
+    # workaround for numpy's buggy finfo on float128 on ppc64 archs
+    if ftype_ == np.longdouble and MACHINE == 'ppc64':
+        # values reported by hdf5
+        nmant = 116
+        maxexp = 1024
+        minexp = -1022
+    elif ftype_ == np.longdouble and MACHINE == 'ppc64le':
+        # values reported by hdf5
+        nmant = 52
+        maxexp = 1024
+        minexp = -1022
+    elif nmant == 63 and finfo.nexp == 15:
+        # This is an 80-bit float, correct mantissa size
+        nmant += 1
+
+    return nmant, maxexp, minexp
+
+
 # === General datatype operations =============================================
 
 @with_phil
@@ -1025,23 +1056,7 @@ cdef class TypeFloatID(TypeAtomicID):
 
         # Handle non-standard exponent and mantissa sizes.
         for ftype_, finfo, size in _available_ftypes:
-            nmant = finfo.nmant
-            maxexp = finfo.maxexp
-            minexp = finfo.minexp
-            # workaround for numpy's buggy finfo on float128 on ppc64 archs
-            if ftype_ == np.longdouble and MACHINE == 'ppc64':
-                # values reported by hdf5
-                nmant = 116
-                maxexp = 1024
-                minexp = -1022
-            elif ftype_ == np.longdouble and MACHINE == 'ppc64le':
-                # values reported by hdf5
-                nmant = 52
-                maxexp = 1024
-                minexp = -1022
-            elif nmant == 63 and finfo.nexp == 15:
-                # This is an 80-bit float, correct mantissa size
-                nmant += 1
+            nmant, maxexp, minexp = _correct_float_info(ftype_, finfo)
             if (size >= self.get_size() and m_size <= nmant and
                 (2**e_size - e_bias - 1) <= maxexp and (1 - e_bias) >= minexp):
                 new_dtype = np.dtype(ftype_).newbyteorder(order)
@@ -1353,29 +1368,30 @@ cdef class TypeEnumID(TypeCompositeID):
 def _get_float_dtype_to_hdf5():
     float_le = {}
     float_be = {}
-    h5_be_list = [IEEE_F16BE, IEEE_F32BE, IEEE_F64BE, IEEE_F128BE]
-    h5_le_list = [IEEE_F16LE, IEEE_F32LE, IEEE_F64LE, IEEE_F128LE]
+    h5_be_list = [IEEE_F16BE, IEEE_F32BE, IEEE_F64BE, IEEE_F128BE,
+                  LDOUBLE_BE]
+    h5_le_list = [IEEE_F16LE, IEEE_F32LE, IEEE_F64LE, IEEE_F128LE,
+                  LDOUBLE_LE]
     for ftype_, finfo, size in _available_ftypes:
+        nmant, maxexp, minexp = _correct_float_info(ftype_, finfo)
         for h5type in h5_be_list:
             spos, epos, esize, mpos, msize = h5type.get_fields()
             ebias = h5type.get_ebias()
-            if (finfo.iexp == esize and finfo.nmant == msize and
-                (finfo.maxexp - 1) == ebias
+            if (finfo.iexp == esize and nmant == msize and
+                (maxexp - 1) == ebias
             ):
                 float_be[ftype_] = h5type
         for h5type in h5_le_list:
             spos, epos, esize, mpos, msize = h5type.get_fields()
             ebias = h5type.get_ebias()
-            if (finfo.iexp == esize and finfo.nmant == msize and
-                (finfo.maxexp - 1) == ebias
+            if (finfo.iexp == esize and nmant == msize and
+                (maxexp - 1) == ebias
             ):
                 float_le[ftype_] = h5type
     if ORDER_NATIVE == H5T_ORDER_LE:
         float_nt = dict(float_le)
     else:
         float_nt = dict(float_be)
-    if np.longdouble not in float_nt:
-        float_nt[np.longdouble] = NATIVE_LDOUBLE
     return float_le, float_be, float_nt
 
 cdef dict _float_le
diff --git a/h5py/tests/hl/test_datatype.py b/h5py/tests/hl/test_datatype.py
index 51bdcb2..e718285 100644
--- a/h5py/tests/hl/test_datatype.py
+++ b/h5py/tests/hl/test_datatype.py
@@ -179,7 +179,6 @@ class TestOffsets(TestCase):
         with h5py.File(fname, 'r') as f:
             self.assertArrayEqual(f['data'], data)
 
-
     def test_out_of_order_offsets(self):
         dt = np.dtype({
             'names' : ['f1', 'f2', 'f3'],
@@ -198,3 +197,26 @@ class TestOffsets(TestCase):
 
         with h5py.File(fname, 'r') as fd:
             self.assertArrayEqual(fd['data'], data)
+
+    def test_float_round_tripping(self):
+        dtypes = set(f for f in np.typeDict.values()
+                     if (np.issubdtype(f, np.floating) or
+                         np.issubdtype(f, np.complexfloating))
+                     )
+
+        dtype_dset_map = {str(j): d
+                          for j, d in enumerate(dtypes)}
+
+        fname = self.mktemp()
+
+        with h5py.File(fname, 'w') as f:
+            for n, d in dtype_dset_map.items():
+                data = np.arange(10,
+                                 dtype=d)
+
+                f.create_dataset(n, data=data)
+
+        with h5py.File(fname, 'r') as f:
+            for n, d in dtype_dset_map.items():
+                ldata = f[n][:]
+                self.assertEqual(ldata.dtype, d)