@@ -25,7 +25,8 @@ def __init__(self, array, out_dtype=None)
25
25
26
26
import numpy as np
27
27
28
- from .casting import int_to_float , as_int , int_abs , type_info
28
+ from .casting import (int_to_float , as_int , int_abs , type_info , floor_exact ,
29
+ best_float )
29
30
from .volumeutils import finite_range , array_to_file
30
31
31
32
@@ -331,12 +332,13 @@ def _range_scale(self):
331
332
out_dtype = self ._out_dtype
332
333
info = type_info (out_dtype )
333
334
t_mn_mx = info ['min' ], info ['max' ]
335
+ big_float = best_float ()
334
336
if out_dtype .kind == 'f' :
335
337
# But we want maximum precision for the calculations. Casting will
336
338
# not lose precision because min/max are of fp type.
337
- t_min , t_max = np .array (t_mn_mx , dtype = np . longdouble )
339
+ t_min , t_max = np .array (t_mn_mx , dtype = big_float )
338
340
else : # (u)int
339
- t_min , t_max = [int_to_float (v , np . longdouble ) for v in t_mn_mx ]
341
+ t_min , t_max = [int_to_float (v , big_float ) for v in t_mn_mx ]
340
342
if self ._out_dtype .kind == 'u' :
341
343
if mn < 0 and mx > 0 :
342
344
raise WriterError ('Cannot scale negative and positive '
@@ -472,27 +474,28 @@ def _range_scale(self):
472
474
self .inter = mn
473
475
return
474
476
# Straight mx-mn can overflow.
477
+ big_float = best_float () # usually longdouble except in win 32
475
478
if mn .dtype .kind == 'f' : # Already floats
476
479
# float64 and below cast correctly to longdouble. Longdouble needs
477
480
# no casting
478
- mn2mx = np .diff (np .array ([mn , mx ], dtype = np . longdouble ))
481
+ mn2mx = np .diff (np .array ([mn , mx ], dtype = big_float ))
479
482
else : # max possible (u)int range is 2**64-1 (int64, uint64)
480
483
# int_to_float covers this range. On windows longdouble is the same
481
484
# as double so mn2mx will be 2**64 - thus overestimating slope
482
485
# slightly. Casting to int needed to allow mx-mn to be larger than
483
486
# the largest (u)int value
484
- mn2mx = int_to_float (as_int (mx ) - as_int (mn ), np . longdouble )
487
+ mn2mx = int_to_float (as_int (mx ) - as_int (mn ), big_float )
485
488
if out_dtype .kind == 'f' :
486
489
# Type range, these are also floats
487
490
info = type_info (out_dtype )
488
491
t_mn_mx = info ['min' ], info ['max' ]
489
492
else :
490
493
t_mn_mx = np .iinfo (out_dtype ).min , np .iinfo (out_dtype ).max
491
- t_mn_mx = [int_to_float (v , np . longdouble ) for v in t_mn_mx ]
494
+ t_mn_mx = [int_to_float (v , big_float ) for v in t_mn_mx ]
492
495
# We want maximum precision for the calculations. Casting will
493
496
# not lose precision because min/max are of fp type.
494
497
assert [v .dtype .kind for v in t_mn_mx ] == ['f' , 'f' ]
495
- scaled_mn2mx = np .diff (np .array (t_mn_mx , dtype = np . longdouble ))
498
+ scaled_mn2mx = np .diff (np .array (t_mn_mx , dtype = big_float ))
496
499
slope = mn2mx / scaled_mn2mx
497
500
self .inter = mn - t_mn_mx [0 ] * slope
498
501
self .slope = slope
0 commit comments