Skip to content

Commit caa04e4

Browse files
committed
BF: allow for PPC64 little endian long doubles
Fix test failures for numpy / PPC 64 little-endian systems. Closes gh-657.
1 parent 897eb31 commit caa04e4

File tree

2 files changed

+31
-24
lines changed

2 files changed

+31
-24
lines changed

nibabel/casting.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,9 @@ def type_info(np_type):
268268
# 80) but in calculations nexp in fact appears to be 11 as for float64
269269
ret.update(dict(width=width))
270270
return ret
271+
if vals == (105, 11, 16): # correctly detected double double
272+
ret.update(dict(nmant=nmant, nexp=nexp, width=width))
273+
return ret
271274
# Oh dear, we don't recognize the type information. Try some known types
272275
# and then give up. At this stage we're expecting exotic longdouble or
273276
# their complex equivalent.

nibabel/tests/test_floating.py

Lines changed: 28 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,16 @@
3030
LD_INFO = type_info(np.longdouble)
3131

3232

33+
def dtt2dict(dtt):
34+
""" Create info dictionary from numpy type
35+
"""
36+
info = np.finfo(dtt)
37+
return dict(min=info.min, max=info.max,
38+
nexp=info.nexp, nmant=info.nmant,
39+
minexp=info.minexp, maxexp=info.maxexp,
40+
width=np.dtype(dtt).itemsize)
41+
42+
3343
def test_type_info():
3444
# Test routine to get min, max, nmant, nexp
3545
for dtt in np.sctypes['int'] + np.sctypes['uint']:
@@ -42,42 +52,36 @@ def test_type_info():
4252
assert_equal(infod['min'].dtype.type, dtt)
4353
assert_equal(infod['max'].dtype.type, dtt)
4454
for dtt in IEEE_floats + [np.complex64, np.complex64]:
45-
info = np.finfo(dtt)
4655
infod = type_info(dtt)
47-
assert_equal(dict(min=info.min, max=info.max,
48-
nexp=info.nexp, nmant=info.nmant,
49-
minexp=info.minexp, maxexp=info.maxexp,
50-
width=np.dtype(dtt).itemsize),
51-
infod)
56+
assert_equal(dtt2dict(dtt), infod)
5257
assert_equal(infod['min'].dtype.type, dtt)
5358
assert_equal(infod['max'].dtype.type, dtt)
5459
# What is longdouble?
55-
info = np.finfo(np.longdouble)
56-
dbl_info = np.finfo(np.float64)
60+
ld_dict = dtt2dict(np.longdouble)
61+
dbl_dict = dtt2dict(np.float64)
5762
infod = type_info(np.longdouble)
58-
width = np.dtype(np.longdouble).itemsize
59-
vals = (info.nmant, info.nexp, width)
63+
ld_dict['width'] = np.dtype(np.longdouble).itemsize
64+
vals = tuple(ld_dict[k] for k in ('nmant', 'nexp', 'width'))
6065
# Information for PPC head / tail doubles from:
6166
# https://developer.apple.com/library/mac/#documentation/Darwin/Reference/Manpages/man3/float.3.html
6267
if vals in ((52, 11, 8), # longdouble is same as double
6368
(63, 15, 12), (63, 15, 16), # intel 80 bit
6469
(112, 15, 16), # real float128
6570
(106, 11, 16)): # PPC head, tail doubles, expected values
66-
assert_equal(dict(min=info.min, max=info.max,
67-
minexp=info.minexp, maxexp=info.maxexp,
68-
nexp=info.nexp, nmant=info.nmant, width=width),
69-
infod)
70-
elif vals == (1, 1, 16): # bust info for PPC head / tail longdoubles
71-
assert_equal(dict(min=dbl_info.min, max=dbl_info.max,
72-
minexp=-1022, maxexp=1024,
73-
nexp=11, nmant=106, width=16),
74-
infod)
71+
pass
72+
elif vals == (105, 11, 16): # bust info for PPC head / tail longdoubles
73+
# min and max broken.
74+
ld_dict['min'] = infod['min']
75+
ld_dict['max'] = infod['max']
76+
elif vals == (1, 1, 16): # another bust info for PPC head / tail longdoubles
77+
ld_dict = dbl_dict.copy()
78+
ld_dict.update(dict(nmant=106, width=16))
7579
elif vals == (52, 15, 12):
76-
exp_res = type_info(np.float64)
77-
exp_res['width'] = width
78-
assert_equal(exp_res, infod)
80+
ld_dict = dbl_dict.copy()
81+
ld_dict['width'] = width
7982
else:
80-
raise ValueError("Unexpected float type to test")
83+
raise ValueError("Unexpected float type {} to test".format(np.longdouble))
84+
assert_equal(ld_dict, infod)
8185

8286

8387
def test_nmant():
@@ -103,7 +107,7 @@ def test_check_nmant_nexp():
103107
# Check against type_info
104108
for t in ok_floats():
105109
ti = type_info(t)
106-
if ti['nmant'] != 106: # This check does not work for PPC double pair
110+
if ti['nmant'] not in (105, 106): # This check does not work for PPC double pair
107111
assert_true(_check_nmant(t, ti['nmant']))
108112
# Test fails for longdouble after blacklisting of OSX powl as of numpy
109113
# 1.12 - see https://github.com/numpy/numpy/issues/8307

0 commit comments

Comments
 (0)