Skip to content

Commit fce4911

Browse files
committed
RF: Remove old int_to_float() hack
1 parent 443ec37 commit fce4911

File tree

5 files changed

+21
-70
lines changed

5 files changed

+21
-70
lines changed

nibabel/arraywriters.py

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ def __init__(self, array, out_dtype=None)
3030
"""
3131
import numpy as np
3232

33-
from .casting import best_float, floor_exact, int_abs, int_to_float, shared_range, type_info
33+
from .casting import best_float, floor_exact, int_abs, shared_range, type_info
3434
from .volumeutils import array_to_file, finite_range
3535

3636

@@ -418,7 +418,7 @@ def _range_scale(self, in_min, in_max):
418418
# not lose precision because min/max are of fp type.
419419
out_min, out_max = np.array((out_min, out_max), dtype=big_float)
420420
else: # (u)int
421-
out_min, out_max = (int_to_float(v, big_float) for v in (out_min, out_max))
421+
out_min, out_max = (big_float(v) for v in (out_min, out_max))
422422
if self._out_dtype.kind == 'u':
423423
if in_min < 0 and in_max > 0:
424424
raise WriterError(
@@ -584,14 +584,13 @@ def _range_scale(self, in_min, in_max):
584584
in_min, in_max = np.array([in_min, in_max], dtype=big_float)
585585
in_range = np.diff([in_min, in_max])
586586
else: # max possible (u)int range is 2**64-1 (int64, uint64)
587-
# int_to_float covers this range. On windows longdouble is the
588-
# same as double so in_range will be 2**64 - thus overestimating
589-
# slope slightly. Casting to int needed to allow in_max-in_min to
590-
# be larger than the largest (u)int value
587+
# On windows longdouble is the same as double so in_range will be 2**64 -
588+
# thus overestimating slope slightly. Casting to int needed to allow
589+
# in_max-in_min to be larger than the largest (u)int value
591590
in_min, in_max = int(in_min), int(in_max)
592-
in_range = int_to_float(in_max - in_min, big_float)
591+
in_range = big_float(in_max - in_min)
593592
# Cast to float for later processing.
594-
in_min, in_max = (int_to_float(v, big_float) for v in (in_min, in_max))
593+
in_min, in_max = (big_float(v) for v in (in_min, in_max))
595594
if out_dtype.kind == 'f':
596595
# Type range, these are also floats
597596
info = type_info(out_dtype)

nibabel/casting.py

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -445,6 +445,7 @@ def as_int(x, check=True):
445445
return ix
446446

447447

448+
@deprecate_with_version('int_to_float(..., dt) is deprecated. Use dt() instead.', '5.2.0', '7.0.0')
448449
def int_to_float(val, flt_type):
449450
"""Convert integer `val` to floating point type `flt_type`
450451
@@ -467,17 +468,7 @@ def int_to_float(val, flt_type):
467468
f : numpy scalar
468469
of type `flt_type`
469470
"""
470-
if flt_type is not np.longdouble:
471-
return flt_type(val)
472-
# The following works around a nasty numpy 1.4.1 bug such that:
473-
# >>> int(np.uint32(2**32-1)
474-
val = int(val)
475-
faval = np.longdouble(0)
476-
while val != 0:
477-
f64 = np.float64(val)
478-
faval += f64
479-
val -= int(f64)
480-
return faval
471+
return flt_type(val)
481472

482473

483474
def floor_exact(val, flt_type):
@@ -524,8 +515,8 @@ def floor_exact(val, flt_type):
524515
val = int(val)
525516
flt_type = np.dtype(flt_type).type
526517
sign = 1 if val > 0 else -1
527-
try: # int_to_float deals with longdouble safely
528-
fval = int_to_float(val, flt_type)
518+
try:
519+
fval = flt_type(val)
529520
except OverflowError:
530521
return sign * np.inf
531522
if not np.isfinite(fval):

nibabel/tests/test_casting.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
float_to_int,
1515
floor_log2,
1616
int_abs,
17-
int_to_float,
1817
longdouble_precision_improved,
1918
sctypes,
2019
shared_range,
@@ -41,7 +40,7 @@ def test_shared_range():
4140
if casted_mx != imax:
4241
# The shared_range have told us that they believe the imax does
4342
# not have an exact representation.
44-
fimax = int_to_float(imax, ft)
43+
fimax = ft(imax)
4544
if np.isfinite(fimax):
4645
assert int(fimax) != imax
4746
# Therefore the imax, cast back to float, and to integer, will
@@ -67,7 +66,7 @@ def test_shared_range():
6766
if casted_mn != imin:
6867
# The shared_range have told us that they believe the imin does
6968
# not have an exact representation.
70-
fimin = int_to_float(imin, ft)
69+
fimin = ft(imin)
7170
if np.isfinite(fimin):
7271
assert int(fimin) != imin
7372
# Therefore the imin, cast back to float, and to integer, will

nibabel/tests/test_floating.py

Lines changed: 7 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
floor_exact,
1616
floor_log2,
1717
have_binary128,
18-
int_to_float,
1918
longdouble_precision_improved,
2019
ok_floats,
2120
on_powerpc,
@@ -127,59 +126,21 @@ def test_check_nmant_nexp():
127126
assert _check_maxexp(t, ti['maxexp'])
128127

129128

130-
def test_int_to_float():
131-
# Convert python integer to floating point
132-
# Standard float types just return cast value
133-
for ie3 in IEEE_floats:
134-
nmant = type_info(ie3)['nmant']
135-
for p in range(nmant + 3):
136-
i = 2**p + 1
137-
assert int_to_float(i, ie3) == ie3(i)
138-
assert int_to_float(-i, ie3) == ie3(-i)
139-
# IEEEs in this case are binary formats only
140-
nexp = floor_log2(type_info(ie3)['max'])
141-
# Values too large for the format
142-
smn, smx = -(2 ** (nexp + 1)), 2 ** (nexp + 1)
143-
if ie3 is np.float64:
144-
with pytest.raises(OverflowError):
145-
int_to_float(smn, ie3)
146-
with pytest.raises(OverflowError):
147-
int_to_float(smx, ie3)
148-
else:
149-
assert int_to_float(smn, ie3) == ie3(smn)
150-
assert int_to_float(smx, ie3) == ie3(smx)
151-
# Longdoubles do better than int, we hope
152-
LD = np.longdouble
153-
# up to integer precision of float64 nmant, we get the same result as for
154-
# casting directly
129+
def test_int_longdouble_np_regression():
130+
# Test longdouble conversion from int works as expected
131+
# Previous versions of numpy would fail, and we used a custom int_to_float()
132+
# function. This test remains to ensure we don't need to bring it back.
155133
nmant = type_info(np.float64)['nmant']
156-
for p in range(nmant + 2): # implicit
157-
i = 2**p - 1
158-
assert int_to_float(i, LD) == LD(i)
159-
assert int_to_float(-i, LD) == LD(-i)
160-
# Above max of float64, we're hosed
161-
nexp64 = floor_log2(type_info(np.float64)['max'])
162-
smn64, smx64 = -(2 ** (nexp64 + 1)), 2 ** (nexp64 + 1)
163-
# The algorithm here implemented goes through float64, so supermax and
164-
# supermin will cause overflow errors
165-
with pytest.raises(OverflowError):
166-
int_to_float(smn64, LD)
167-
with pytest.raises(OverflowError):
168-
int_to_float(smx64, LD)
169-
try:
170-
nmant = type_info(np.longdouble)['nmant']
171-
except FloatingError: # don't know where to test
172-
return
173134
# test we recover precision just above nmant
174135
i = 2 ** (nmant + 1) - 1
175-
assert int(int_to_float(i, LD)) == i
176-
assert int(int_to_float(-i, LD)) == -i
136+
assert int(np.longdouble(i)) == i
137+
assert int(np.longdouble(-i)) == -i
177138
# If longdouble can cope with 2**64, test
178139
if nmant >= 63:
179140
# Check conversion to int; the line below causes an error subtracting
180141
# ints / uint64 values, at least for Python 3.3 and numpy dev 1.8
181142
big_int = np.uint64(2**64 - 1)
182-
assert int(int_to_float(big_int, LD)) == big_int
143+
assert int(np.longdouble(big_int)) == big_int
183144

184145

185146
def test_int_np_regression():

nibabel/tests/test_removalschedule.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
'8.0.0',
1919
[
2020
('nibabel.casting', 'as_int'),
21+
('nibabel.casting', 'int_to_float'),
2122
('nibabel.tmpdirs', 'TemporaryDirectory'),
2223
],
2324
),

0 commit comments

Comments
 (0)