@@ -99,8 +99,10 @@ def set_printoptions(precision=None, threshold=None, edgeitems=None,
9999
100100 Parameters
101101 ----------
102- precision : int, optional
102+ precision : int or None , optional
103103 Number of digits of precision for floating point output (default 8).
104+ May be `None` if `floatmode` is not `fixed`, to print as many digits as
105+ necessary to uniquely specify the value.
104106 threshold : int, optional
105107 Total number of array elements which trigger summarization
106108 rather than full repr (default 1000).
@@ -240,6 +242,8 @@ def set_printoptions(precision=None, threshold=None, edgeitems=None,
240242# set the C variable for legacy mode
241243if _format_options ['legacy' ]== '1.13' :
242244set_legacy_print_mode (113 )
245+ # reset the sign option in legacy mode to avoid confusion
246+ _format_options ['sign' ]= '-'
243247elif _format_options ['legacy' ]is False :
244248set_legacy_print_mode (0 )
245249
@@ -469,7 +473,7 @@ def array2string(a, max_line_width=None, precision=None,
469473 max_line_width : int, optional
470474 The maximum number of columns the string should span. Newline
471475 characters splits the string appropriately after array elements.
472- precision : int, optional
476+ precision : int or None , optional
473477 Floating point precision. Default is the current printing
474478 precision (usually 8), which can be altered using `set_printoptions`.
475479 suppress_small : bool, optional
@@ -749,6 +753,13 @@ def recurser(index, hanging_indent, curr_width):
749753curr_width = line_width )
750754
751755
756+ def _none_or_positive_arg (x ,name ):
757+ if x is None :
758+ return - 1
759+ if x < 0 :
760+ raise ValueError ("{} must be >= 0" .format (name ))
761+ return x
762+
752763class FloatingFormat (object ):
753764""" Formatter for subtypes of np.floating """
754765def __init__ (self ,data ,precision ,floatmode ,suppress_small ,sign = False ,
@@ -759,17 +770,18 @@ def __init__(self, data, precision, floatmode, suppress_small, sign=False,
759770
760771self ._legacy = kwarg .get ('legacy' ,False )
761772if self ._legacy == '1.13' :
762- sign = '-' if data .shape == ()else ' '
773+ # when not 0d, legacy does not support '-'
774+ if data .shape != ()and sign == '-' :
775+ sign = ' '
763776
764777self .floatmode = floatmode
765778if floatmode == 'unique' :
766- self .precision = - 1
779+ self .precision = None
767780else :
768- if precision < 0 :
769- raise ValueError (
770- "precision must be >= 0 in {} mode" .format (floatmode ))
771781self .precision = precision
772782
783+ self .precision = _none_or_positive_arg (self .precision ,'precision' )
784+
773785self .suppress_small = suppress_small
774786self .sign = sign
775787self .exp_format = False
@@ -812,11 +824,9 @@ def fillFormat(self, data):
812824self .trim = 'k'
813825self .precision = max (len (s )for s in frac_part )
814826
815- # for back-compatibility with np 1.13, usetwo spaces and full prec
827+ # for back-compat with np 1.13, use2 spaces & sign and full prec
816828if self ._legacy == '1.13' :
817- # undo addition of sign pos below
818- will_add_sign = all (finite_vals > 0 )and self .sign == ' '
819- self .pad_left = 3 - will_add_sign
829+ self .pad_left = 3
820830else :
821831# this should be only 1 or 2. Can be calculated from sign.
822832self .pad_left = max (len (s )for s in int_part )
@@ -835,7 +845,10 @@ def fillFormat(self, data):
835845sign = self .sign == '+' )
836846for x in finite_vals )
837847int_part ,frac_part = zip (* (s .split ('.' )for s in strs ))
838- self .pad_left = max (len (s )for s in int_part )
848+ if self ._legacy == '1.13' :
849+ self .pad_left = 1 + max (len (s .lstrip ('-+' ))for s in int_part )
850+ else :
851+ self .pad_left = max (len (s )for s in int_part )
839852self .pad_right = max (len (s )for s in frac_part )
840853self .exp_size = - 1
841854
@@ -847,9 +860,10 @@ def fillFormat(self, data):
847860self .unique = True
848861self .trim = '.'
849862
850- # account for sign = ' ' by adding one to pad_left
851- if all (finite_vals >= 0 )and self .sign == ' ' :
852- self .pad_left += 1
863+ if self ._legacy != '1.13' :
864+ # account for sign = ' ' by adding one to pad_left
865+ if self .sign == ' ' and not any (np .signbit (finite_vals )):
866+ self .pad_left += 1
853867
854868# if there are non-finite values, may need to increase pad_left
855869if data .size != finite_vals .size :
@@ -902,7 +916,6 @@ def __init__(self, *args, **kwargs):
902916DeprecationWarning ,stacklevel = 2 )
903917super (LongFloatFormat ,self ).__init__ (* args ,** kwargs )
904918
905-
906919def format_float_scientific (x ,precision = None ,unique = True ,trim = 'k' ,
907920sign = False ,pad_left = None ,exp_digits = None ):
908921"""
@@ -915,9 +928,9 @@ def format_float_scientific(x, precision=None, unique=True, trim='k',
915928 ----------
916929 x : python float or numpy floating scalar
917930 Value to format.
918- precision : non-negative integer, optional
919- Maximum number offractional digits to print. May beomitted if
920- `unique` is ` True`, butis required if unique is `False`.
931+ precision : non-negative integer or None , optional
932+ Maximum number of digits to print. May beNone if `unique` is
933+ `True`, butmust be an integer if unique is `False`.
921934 unique : boolean, optional
922935 If `True`, use a digit-generation strategy which gives the shortest
923936 representation which uniquely identifies the floating-point number from
@@ -962,9 +975,9 @@ def format_float_scientific(x, precision=None, unique=True, trim='k',
962975 >>> np.format_float_scientific(s, exp_digits=4)
963976 '1.23e+0024'
964977 """
965- precision = - 1 if precision is None else precision
966- pad_left = - 1 if pad_left is None else pad_left
967- exp_digits = - 1 if exp_digits is None else exp_digits
978+ precision = _none_or_positive_arg ( precision , ' precision' )
979+ pad_left = _none_or_positive_arg ( pad_left , ' pad_left' )
980+ exp_digits = _none_or_positive_arg ( exp_digits , ' exp_digits' )
968981return dragon4_scientific (x ,precision = precision ,unique = unique ,
969982trim = trim ,sign = sign ,pad_left = pad_left ,
970983exp_digits = exp_digits )
@@ -982,9 +995,9 @@ def format_float_positional(x, precision=None, unique=True,
982995 ----------
983996 x : python float or numpy floating scalar
984997 Value to format.
985- precision : non-negative integer, optional
986- Maximum number of digits to print. May beomitted if `unique` is
987- `True`, butis required if unique is `False`.
998+ precision : non-negative integer or None , optional
999+ Maximum number of digits to print. May beNone if `unique` is
1000+ `True`, butmust be an integer if unique is `False`.
9881001 unique : boolean, optional
9891002 If `True`, use a digit-generation strategy which gives the shortest
9901003 representation which uniquely identifies the floating-point number from
@@ -1035,9 +1048,9 @@ def format_float_positional(x, precision=None, unique=True,
10351048 >>> np.format_float_positional(np.float16(0.3), unique=False, precision=10)
10361049 '0.3000488281'
10371050 """
1038- precision = - 1 if precision is None else precision
1039- pad_left = - 1 if pad_left is None else pad_left
1040- pad_right = - 1 if pad_right is None else pad_right
1051+ precision = _none_or_positive_arg ( precision , ' precision' )
1052+ pad_left = _none_or_positive_arg ( pad_left , ' pad_left' )
1053+ pad_right = _none_or_positive_arg ( pad_right , ' pad_right' )
10411054return dragon4_positional (x ,precision = precision ,unique = unique ,
10421055fractional = fractional ,trim = trim ,
10431056sign = sign ,pad_left = pad_left ,
@@ -1075,15 +1088,25 @@ def __init__(self, x, precision, floatmode, suppress_small,
10751088if isinstance (sign ,bool ):
10761089sign = '+' if sign else '-'
10771090
1078- self .real_format = FloatingFormat (x .real ,precision ,floatmode ,
1091+ floatmode_real = floatmode_imag = floatmode
1092+ if kwarg .get ('legacy' ,False )== '1.13' :
1093+ floatmode_real = 'maxprec_equal'
1094+ floatmode_imag = 'maxprec'
1095+
1096+ self .real_format = FloatingFormat (x .real ,precision ,floatmode_real ,
10791097suppress_small ,sign = sign ,** kwarg )
1080- self .imag_format = FloatingFormat (x .imag ,precision ,floatmode ,
1098+ self .imag_format = FloatingFormat (x .imag ,precision ,floatmode_imag ,
10811099suppress_small ,sign = '+' ,** kwarg )
10821100
10831101def __call__ (self ,x ):
10841102r = self .real_format (x .real )
10851103i = self .imag_format (x .imag )
1086- return r + i + 'j'
1104+
1105+ # add the 'j' before the terminal whitespace in i
1106+ sp = len (i .rstrip ())
1107+ i = i [:sp ]+ 'j' + i [sp :]
1108+
1109+ return r + i
10871110
10881111# for back-compatibility, we keep the classes for each complex type too
10891112class ComplexFormat (ComplexFloatingFormat ):