From 6cbd724f75f25cdaa7cf68fd9743064b77fbf787 Mon Sep 17 00:00:00 2001 From: Anne Archibald Date: Wed, 12 Aug 2015 17:46:14 +0200 Subject: BUG: fix #4381: precision loss on string -> longdouble conversion Avoid going through python floats when converting string to longdouble. This makes it dramatically easier to produce full-precision long double numbers. Fixed are the constructor (np.longdouble("1.01")), np.fromfile, np.fromstring, np.loadtxt, and np.genfromtxt (and functions based on it). Also fixed is precision loss when using np.tofile. This also fixes #1481, poor handling of bad data in fromfile and fromstring. If the function strtod_l is not available, almost none of this will work, and many tests will fail. --- numpy/lib/_iotools.py | 13 +++++++++++++ numpy/lib/npyio.py | 2 ++ 2 files changed, 15 insertions(+) (limited to 'numpy/lib') diff --git a/numpy/lib/_iotools.py b/numpy/lib/_iotools.py index 44bd48df7..dfdc38b72 100644 --- a/numpy/lib/_iotools.py +++ b/numpy/lib/_iotools.py @@ -527,6 +527,7 @@ class StringConverter(object): _mapper.extend([(nx.floating, float, nx.nan), (complex, _bytes_to_complex, nx.nan + 0j), + (nx.longdouble, nx.longdouble, nx.nan), (nx.string_, bytes, asbytes('???'))]) (_defaulttype, _defaultfunc, _defaultfill) = zip(*_mapper) @@ -643,6 +644,18 @@ class StringConverter(object): else: self.default = default break + # if a converter for the specific dtype is available use that + last_func = func + for (i, (deftype, func, default_def)) in enumerate(self._mapper): + if dtype.type == deftype: + _status = i + last_func = func + if default is None: + self.default = default_def + else: + self.default = default + break + func = last_func if _status == -1: # We never found a match in the _mapper... _status = 0 diff --git a/numpy/lib/npyio.py b/numpy/lib/npyio.py index 86d757630..12052a08e 100644 --- a/numpy/lib/npyio.py +++ b/numpy/lib/npyio.py @@ -667,6 +667,8 @@ def _getconv(dtype): return np.int64 if issubclass(typ, np.integer): return lambda x: int(float(x)) + elif issubclass(typ, np.longdouble): + return np.longdouble elif issubclass(typ, np.floating): return floatconv elif issubclass(typ, np.complex): -- cgit v1.2.1