comparison scripts/general/num2str.m @ 14537:f8e041f11b18

num2str.m: Update function to address bug #36117 and bug #36121. * num2str.m: Return decimal, not floating point, for integer values less than 1e10 (bug #36117). Return correct result when integer input exceeds intmax (bug #36121). This checkin is a benchmark which still uses Octaves output format string. The next checkin will change the output format to match Matlab's.
author Rik <octave@nomad.inbox5.com>
date Sat, 07 Apr 2012 13:10:20 -0700
parents f3d52523cde1
children 34c932e669c8
comparison
equal deleted inserted replaced
14536:6d5c951ec520 14537:f8e041f11b18
58 ## @seealso{sprintf, int2str, mat2str} 58 ## @seealso{sprintf, int2str, mat2str}
59 ## @end deftypefn 59 ## @end deftypefn
60 60
61 ## Author: jwe 61 ## Author: jwe
62 62
63 ## FIXME: Matlab output is essentially sprintf ("%p+8.pg", x)
64 ## where precision p is log10(x) + 4. This produces differently sized
65 ## columns for matrix input with both integer and floating point values
66 ## which can look rather odd. For the time being (2012/04/07) we prefer
67 ## Octave's output over strict compatibility.
68
69 ## FIXME: Switch from "%d" decimal format to "%g" floating point format
70 ## is based on intmax ("int32"). On 64-bit machines we should probably use
71 ## intmax ("int64").
72
63 function retval = num2str (x, arg) 73 function retval = num2str (x, arg)
64 74
65 if (nargin != 1 && nargin != 2) 75 if (nargin != 1 && nargin != 2)
66 print_usage (); 76 print_usage ();
67 endif 77 endif
68 78
69 if (ischar (x)) 79 if (ischar (x))
70 retval = x; 80 retval = x;
71 elseif (isempty (x)) 81 elseif (isempty (x))
72 retval = ""; 82 retval = "";
73 elseif (iscomplex (x)) 83 elseif (isreal (x))
84 if (nargin == 2)
85 if (ischar (arg))
86 fmt = arg;
87 else
88 if (isnumeric (x) && x == fix (x)
89 && abs (x) < min (10 .^ arg, intmax ("int32")))
90 fmt = sprintf ("%%%dd ", arg);
91 else
92 fmt = sprintf ("%%%d.%dg", arg+7, arg);
93 endif
94 endif
95 else
96 if (isnumeric (x) && x == fix (x) && abs (x) < 1e10)
97 if (any (x(:) != 0))
98 dgt = floor (log10 (max (abs (x(:))))) + (any (x(:) < 0)) + 2;
99 else
100 dgt = 2;
101 endif
102 if (any (abs (x(:)) > intmax ("int32")))
103 fmt = sprintf ("%%%dg ", dgt);
104 else
105 fmt = sprintf ("%%%dd ", dgt);
106 endif
107 elseif (isscalar (x))
108 fmt = "%11.5g";
109 else
110 fmt = "%11.5g";
111 endif
112 endif
113 fmt = cstrcat (deblank (repmat (fmt, 1, columns (x))), "\n");
114 nd = ndims (x);
115 tmp = sprintf (fmt, permute (x, [2, 1, 3:nd]));
116 tmp(end) = "";
117 retval = strtrim (char (strsplit (tmp, "\n")));
118 else # complex x
74 if (nargin == 2) 119 if (nargin == 2)
75 if (ischar (arg)) 120 if (ischar (arg))
76 fmt = cstrcat (arg, "%-+", arg(2:end), "i"); 121 fmt = cstrcat (arg, "%-+", arg(2:end), "i");
77 else 122 else
78 if (isnumeric (x) && x == fix (x) && abs (x) < (10 .^ arg)) 123 if (isnumeric (x) && x == fix (x)
124 && abs (x) < min (10 .^ arg, intmax ("int32")))
79 fmt = sprintf ("%%%dd%%-+%ddi ", arg, arg); 125 fmt = sprintf ("%%%dd%%-+%ddi ", arg, arg);
80 else 126 else
81 fmt = sprintf ("%%%d.%dg%%-+%d.%dgi", arg+7, arg, arg+7, arg); 127 fmt = sprintf ("%%%d.%dg%%-+%d.%dgi", arg+7, arg, arg+7, arg);
82 endif 128 endif
83 endif 129 endif
84 else 130 else
85 ## Setup a suitable format string 131 ## Setup a suitable format string
86 if (isnumeric (x) && x == fix (x) && abs (x) < 1e10) 132 if (isnumeric (x) && x == fix (x) && abs (x) < 1e10)
87 if (max (abs (real (x(:)))) == 0) 133 if (any (real (x(:)) != 0))
88 dgt1 = 2;
89 else
90 dgt1 = ceil (log10 (max (max (abs (real (x(:)))), 134 dgt1 = ceil (log10 (max (max (abs (real (x(:)))),
91 max (abs (imag (x(:))))))) + 2; 135 max (abs (imag (x(:))))))) + 2;
92 endif 136 else
93 dgt2 = dgt1 - (min (real (x(:))) >= 0); 137 dgt1 = 2;
94 138 endif
95 if (length (abs (x) == x) > 0) 139 dgt2 = dgt1 - (any (real (x(:)) >= 0));
140
141 if (any (abs (x(:)) > intmax ("int32")))
96 fmt = sprintf("%%%dg%%+-%dgi ", dgt2, dgt1); 142 fmt = sprintf("%%%dg%%+-%dgi ", dgt2, dgt1);
97 else 143 else
98 fmt = sprintf("%%%dd%%+-%ddi ", dgt2, dgt1); 144 fmt = sprintf("%%%dd%%+-%ddi ", dgt2, dgt1);
99 endif 145 endif
100 elseif (isscalar (x)) 146 elseif (isscalar (x))
104 endif 150 endif
105 endif 151 endif
106 152
107 ## Manipulate the complex value to have real values in the odd 153 ## Manipulate the complex value to have real values in the odd
108 ## columns and imaginary values in the even columns. 154 ## columns and imaginary values in the even columns.
109 sz = size (x); 155 nc = columns (x);
110 nc = sz(2);
111 nd = ndims (x); 156 nd = ndims (x);
112 perm = fix ([1:0.5:nc+0.5]); 157 perm = fix ([1:0.5:nc+0.5]);
113 perm(2:2:2*nc) = perm(2:2:2*nc) + nc; 158 perm(2:2:2*nc) = perm(2:2:2*nc) + nc;
114 idx = repmat ({':'}, nd, 1); 159 idx = repmat ({':'}, nd, 1);
115 idx{2} = perm; 160 idx{2} = perm;
135 else 180 else
136 tmp = tmp2; 181 tmp = tmp2;
137 endif 182 endif
138 endwhile 183 endwhile
139 184
140 tmp(length (tmp)) = ""; 185 tmp(end) = "";
141 retval = char (strtrim (strsplit (tmp, "\n")));
142 else
143 if (nargin == 2)
144 if (ischar (arg))
145 fmt = arg;
146 else
147 if (isnumeric (x) && x == fix (x) && abs (x) < (10 .^ arg))
148 fmt = sprintf ("%%%dd ", arg);
149 else
150 fmt = sprintf ("%%%d.%dg", arg+7, arg);
151 endif
152 endif
153 else
154 if (isnumeric (x) && x == fix (x) && abs (x) < 1e10)
155 if (max (abs (x(:))) == 0)
156 dgt = 2;
157 else
158 dgt = floor (log10 (max (abs(x(:))))) + (min (real (x(:))) < 0) + 2;
159 endif
160 if (length (abs (x) == x) > 0)
161 fmt = sprintf ("%%%dg ", dgt);
162 else
163 fmt = sprintf ("%%%dd ", dgt);
164 endif
165 elseif (isscalar (x))
166 fmt = "%11.5g";
167 else
168 fmt = "%11.5g";
169 endif
170 endif
171 fmt = cstrcat (deblank (repmat (fmt, 1, columns (x))), "\n");
172 nd = ndims (x);
173 tmp = sprintf (fmt, permute (x, [2, 1, 3:nd]));
174 tmp(length (tmp)) = "";
175 retval = strtrim (char (strsplit (tmp, "\n"))); 186 retval = strtrim (char (strsplit (tmp, "\n")));
176 endif 187 endif
177 188
178 endfunction 189 endfunction
179 190
182 %!assert (num2str (1.23), "1.23") 193 %!assert (num2str (1.23), "1.23")
183 %!assert (num2str (123.456, 4), "123.5") 194 %!assert (num2str (123.456, 4), "123.5")
184 %!assert (num2str ([1, 1.34; 3, 3.56], "%5.1f"), ["1.0 1.3"; "3.0 3.6"]) 195 %!assert (num2str ([1, 1.34; 3, 3.56], "%5.1f"), ["1.0 1.3"; "3.0 3.6"])
185 %!assert (num2str (1.234 + 27.3i), "1.234+27.3i") 196 %!assert (num2str (1.234 + 27.3i), "1.234+27.3i")
186 197
198 %!assert (num2str (19440606), "19440606")
199 %!assert (num2str (2^33), "8.58993e+09")
200 %!assert (num2str (-2^33), "-8.58993e+09")
201 %!assert (num2str (2^33+1i), "8.58993e+09+1i")
202 %!assert (num2str (-2^33+1i), "-8.58993e+09+1i")
203
187 %!error num2str () 204 %!error num2str ()
188 %!error num2str (1, 2, 3) 205 %!error num2str (1, 2, 3)
189 206