@@ -411,15 +411,16 @@ def _do_scaling(self):
411411 def _iu2iu (self ):
412412 # (u)int to (u)int scaling
413413 mn , mx = self .finite_range ()
414- if self ._out_dtype .kind == 'u' :
414+ out_dt = self ._out_dtype
415+ if out_dt .kind == 'u' :
415416 # We're checking for a sign flip. This can only work for uint
416417 # output, because, for int output, the abs min of the type is
417- # greater than the abs max, so the data either fit into the range
418- # (tested for in _do_scaling), or this test can't pass
419- # Need abs that deals with max neg ints. abs problem only arises
420- # when all the data is set to max neg integer value
421- imax = np . iinfo (self ._out_dtype ). max
422- if mx <= 0 and int_abs (mn ) <= imax : # sign flip enough?
418+ # greater than the abs max, so the data either fits into the range
419+ # (tested for in _do_scaling), or this test can't pass. Need abs
420+ # that deals with max neg ints. abs problem only arises when all
421+ # the data is set to max neg integer value
422+ o_min , o_max = shared_range (self .scaler_dtype , out_dt )
423+ if mx <= 0 and int_abs (mn ) <= as_int ( o_max ) : # sign flip enough?
423424 # -1.0 * arr will be in scaler_dtype precision
424425 self .slope = - 1.0
425426 return
@@ -563,15 +564,19 @@ def _iu2iu(self):
563564 # range may be greater than the largest integer for this type.
564565 # as_int needed to work round numpy 1.4.1 int casting bug
565566 out_dtype = self ._out_dtype
566- t_min , t_max = np .iinfo (out_dtype ).min , np .iinfo (out_dtype ).max
567- type_range = as_int (t_max ) - as_int (t_min )
567+ # Options in this method are scaling using intercept only. These will
568+ # have to pass through ``self.scaler_dtype`` (because the intercept is
569+ # in this type).
570+ o_min , o_max = [as_int (v )
571+ for v in shared_range (self .scaler_dtype , out_dtype )]
572+ type_range = o_max - o_min
568573 mn2mx = mx - mn
569574 if mn2mx <= type_range : # might offset be enough?
570- if t_min == 0 : # uint output - take min to 0
575+ if o_min == 0 : # uint output - take min to 0
571576 # decrease offset with floor_exact, meaning mn >= t_min after
572577 # subtraction. But we may have pushed the data over t_max,
573578 # which we check below
574- inter = floor_exact (mn - t_min , self .scaler_dtype )
579+ inter = floor_exact (mn - o_min , self .scaler_dtype )
575580 else : # int output - take midpoint to 0
576581 # ceil below increases inter, pushing scale up to 0.5 towards
577582 # -inf, because ints have abs min == abs max + 1
@@ -581,15 +586,16 @@ def _iu2iu(self):
581586 inter = floor_exact (midpoint , self .scaler_dtype )
582587 # Need to check still in range after floor_exact-ing
583588 int_inter = as_int (inter )
584- assert mn - int_inter >= t_min
585- if mx - int_inter <= t_max :
589+ assert mn - int_inter >= o_min
590+ if mx - int_inter <= o_max :
586591 self .inter = inter
587592 return
588593 # Try slope options (sign flip) and then range scaling
589594 super (SlopeInterArrayWriter , self )._iu2iu ()
590595
591596 def _range_scale (self , in_min , in_max ):
592- """ Calculate scaling, intercept based on data range and output type """
597+ """ Calculate scaling, intercept based on data range and output type
598+ """
593599 if in_max == in_min : # Only one number in array
594600 self .slope = 1.
595601 self .inter = in_min
@@ -604,10 +610,10 @@ def _range_scale(self, in_min, in_max):
604610 in_min , in_max = np .array ([in_min , in_max ], dtype = big_float )
605611 in_range = np .diff ([in_min , in_max ])
606612 else : # max possible (u)int range is 2**64-1 (int64, uint64)
607- # int_to_float covers this range. On windows longdouble is the same
608- # as double so in_range will be 2**64 - thus overestimating slope
609- # slightly. Casting to int needed to allow in_max-in_min to be larger than
610- # the largest (u)int value
613+ # int_to_float covers this range. On windows longdouble is the
614+ # same as double so in_range will be 2**64 - thus overestimating
615+ # slope slightly. Casting to int needed to allow in_max-in_min to
616+ # be larger than the largest (u)int value
611617 in_min , in_max = as_int (in_min ), as_int (in_max )
612618 in_range = int_to_float (in_max - in_min , big_float )
613619 # Cast to float for later processing.
@@ -624,13 +630,13 @@ def _range_scale(self, in_min, in_max):
624630 # raise an error when writing
625631 out_min , out_max = shared_range (working_dtype , out_dtype )
626632 out_min , out_max = np .array ((out_min , out_max ), dtype = big_float )
627- # We want maximum precision for the calculations. Casting will
628- # not lose precision because min/max are of fp type.
633+ # We want maximum precision for the calculations. Casting will not lose
634+ # precision because min/max are of fp type.
629635 assert [v .dtype .kind for v in (out_min , out_max )] == ['f' , 'f' ]
630636 out_range = out_max - out_min
631637 """
632- Think of the input values as a line starting (left) at in_min and ending
633- (right) at in_max.
638+ Think of the input values as a line starting (left) at in_min and
639+ ending (right) at in_max.
634640
635641 The output values will be a line starting at out_min and ending at
636642 out_max.
@@ -666,20 +672,20 @@ def _range_scale(self, in_min, in_max):
666672 We can't change the range of the saved data (the whole range of the
667673 integer type) or the range of the output data (the values we input). We
668674 can change the intermediate values ``saved_data * slope`` by choosing
669- the sign of the slope to match the in_min or in_max to the left or right
670- end of the saved data range.
675+ the sign of the slope to match the in_min or in_max to the left or
676+ right end of the saved data range.
671677
672- If the out_dtype is signed int, then abs(out_min) = abs(out_max) + 1 and
673- the absolute value and therefore precision for values at the left and
674- right of the saved data range are very similar (e.g. -128 * slope, 127 *
675- slope respectively).
678+ If the out_dtype is signed int, then abs(out_min) = abs(out_max) + 1
679+ and the absolute value and therefore precision for values at the left
680+ and right of the saved data range are very similar (e.g. -128 * slope,
681+ 127 * slope respectively).
676682
677- If the out_dtype is unsigned int, then the absolute value at the left is
678- 0 and the precision is much higher than for the right end of the range
679- (e.g. 0 * slope, 255 * slope).
683+ If the out_dtype is unsigned int, then the absolute value at the left
684+ is 0 and the precision is much higher than for the right end of the
685+ range (e.g. 0 * slope, 255 * slope).
680686
681- If the out_dtype is unsigned int then we choose the sign of the slope to
682- match the smaller of the in_min, in_max to the zero end of the saved
687+ If the out_dtype is unsigned int then we choose the sign of the slope
688+ to match the smaller of the in_min, in_max to the zero end of the saved
683689 range.
684690 """
685691 if out_min == 0 and np .abs (in_max ) < np .abs (in_min ):
0 commit comments