Mercurial > hg > octave-nkf
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 |