comparison libinterp/corefcn/pr-output.cc @ 16892:68fc671a9339

maint: Collapse interpfcn and interpfcn-core directories into corefcn directory. * libgui/src/module.mk: Remove -I references to interp-core, interpfcn, add reference to corefcn. * libinterp/Makefile.am: Remove -I references to interp-core, interpfcn, add reference to corefcn. * libinterp/corefcn/module.mk: Add files from interp-core, interpfcn to build system. Copy over special rules from module.mk files in interp-core andd interpfcn. * src/Makefile.am: Replace references to interp-core, interpfcn with those to corefcn. * libinterp/corefcn/Cell.cc, libinterp/corefcn/Cell.h, libinterp/corefcn/action-container.h, libinterp/corefcn/c-file-ptr-stream.cc, libinterp/corefcn/c-file-ptr-stream.h, libinterp/corefcn/comment-list.cc, libinterp/corefcn/comment-list.h, libinterp/corefcn/cutils.c, libinterp/corefcn/cutils.h, libinterp/corefcn/data.cc, libinterp/corefcn/data.h, libinterp/corefcn/debug.cc, libinterp/corefcn/debug.h, libinterp/corefcn/defaults.cc, libinterp/corefcn/defaults.in.h, libinterp/corefcn/defun-dld.h, libinterp/corefcn/defun-int.h, libinterp/corefcn/defun.cc, libinterp/corefcn/defun.h, libinterp/corefcn/dirfns.cc, libinterp/corefcn/dirfns.h, libinterp/corefcn/display.cc, libinterp/corefcn/display.h, libinterp/corefcn/dynamic-ld.cc, libinterp/corefcn/dynamic-ld.h, libinterp/corefcn/error.cc, libinterp/corefcn/error.h, libinterp/corefcn/event-queue.h, libinterp/corefcn/file-io.cc, libinterp/corefcn/file-io.h, libinterp/corefcn/gl-render.cc, libinterp/corefcn/gl-render.h, libinterp/corefcn/gl2ps-renderer.cc, libinterp/corefcn/gl2ps-renderer.h, libinterp/corefcn/gl2ps.c, libinterp/corefcn/gl2ps.h, libinterp/corefcn/graphics.cc, libinterp/corefcn/graphics.in.h, libinterp/corefcn/gripes.cc, libinterp/corefcn/gripes.h, libinterp/corefcn/help.cc, libinterp/corefcn/help.h, libinterp/corefcn/hook-fcn.cc, libinterp/corefcn/hook-fcn.h, libinterp/corefcn/input.cc, libinterp/corefcn/input.h, libinterp/corefcn/jit-ir.cc, libinterp/corefcn/jit-ir.h, libinterp/corefcn/jit-typeinfo.cc, libinterp/corefcn/jit-typeinfo.h, libinterp/corefcn/jit-util.cc, libinterp/corefcn/jit-util.h, libinterp/corefcn/load-path.cc, libinterp/corefcn/load-path.h, libinterp/corefcn/load-save.cc, libinterp/corefcn/load-save.h, libinterp/corefcn/ls-ascii-helper.cc, libinterp/corefcn/ls-ascii-helper.h, libinterp/corefcn/ls-hdf5.cc, libinterp/corefcn/ls-hdf5.h, libinterp/corefcn/ls-mat-ascii.cc, libinterp/corefcn/ls-mat-ascii.h, libinterp/corefcn/ls-mat4.cc, libinterp/corefcn/ls-mat4.h, libinterp/corefcn/ls-mat5.cc, libinterp/corefcn/ls-mat5.h, libinterp/corefcn/ls-oct-ascii.cc, libinterp/corefcn/ls-oct-ascii.h, libinterp/corefcn/ls-oct-binary.cc, libinterp/corefcn/ls-oct-binary.h, libinterp/corefcn/ls-utils.cc, libinterp/corefcn/ls-utils.h, libinterp/corefcn/matherr.c, libinterp/corefcn/mex.cc, libinterp/corefcn/mex.h, libinterp/corefcn/mexproto.h, libinterp/corefcn/mxarray.in.h, libinterp/corefcn/oct-errno.h, libinterp/corefcn/oct-errno.in.cc, libinterp/corefcn/oct-fstrm.cc, libinterp/corefcn/oct-fstrm.h, libinterp/corefcn/oct-hdf5.h, libinterp/corefcn/oct-hist.cc, libinterp/corefcn/oct-hist.h, libinterp/corefcn/oct-iostrm.cc, libinterp/corefcn/oct-iostrm.h, libinterp/corefcn/oct-lvalue.cc, libinterp/corefcn/oct-lvalue.h, libinterp/corefcn/oct-map.cc, libinterp/corefcn/oct-map.h, libinterp/corefcn/oct-obj.cc, libinterp/corefcn/oct-obj.h, libinterp/corefcn/oct-prcstrm.cc, libinterp/corefcn/oct-prcstrm.h, libinterp/corefcn/oct-procbuf.cc, libinterp/corefcn/oct-procbuf.h, libinterp/corefcn/oct-stdstrm.h, libinterp/corefcn/oct-stream.cc, libinterp/corefcn/oct-stream.h, libinterp/corefcn/oct-strstrm.cc, libinterp/corefcn/oct-strstrm.h, libinterp/corefcn/oct.h, libinterp/corefcn/octave-link.cc, libinterp/corefcn/octave-link.h, libinterp/corefcn/pager.cc, libinterp/corefcn/pager.h, libinterp/corefcn/pr-output.cc, libinterp/corefcn/pr-output.h, libinterp/corefcn/procstream.cc, libinterp/corefcn/procstream.h, libinterp/corefcn/profiler.cc, libinterp/corefcn/profiler.h, libinterp/corefcn/pt-jit.cc, libinterp/corefcn/pt-jit.h, libinterp/corefcn/sighandlers.cc, libinterp/corefcn/sighandlers.h, libinterp/corefcn/siglist.c, libinterp/corefcn/siglist.h, libinterp/corefcn/sparse-xdiv.cc, libinterp/corefcn/sparse-xdiv.h, libinterp/corefcn/sparse-xpow.cc, libinterp/corefcn/sparse-xpow.h, libinterp/corefcn/symtab.cc, libinterp/corefcn/symtab.h, libinterp/corefcn/sysdep.cc, libinterp/corefcn/sysdep.h, libinterp/corefcn/toplev.cc, libinterp/corefcn/toplev.h, libinterp/corefcn/txt-eng-ft.cc, libinterp/corefcn/txt-eng-ft.h, libinterp/corefcn/txt-eng.h, libinterp/corefcn/unwind-prot.cc, libinterp/corefcn/unwind-prot.h, libinterp/corefcn/utils.cc, libinterp/corefcn/utils.h, libinterp/corefcn/variables.cc, libinterp/corefcn/variables.h, libinterp/corefcn/workspace-element.h, libinterp/corefcn/xdiv.cc, libinterp/corefcn/xdiv.h, libinterp/corefcn/xgl2ps.c, libinterp/corefcn/xnorm.cc, libinterp/corefcn/xnorm.h, libinterp/corefcn/xpow.cc, libinterp/corefcn/xpow.h, libinterp/corefcn/zfstream.cc, libinterp/corefcn/zfstream.h: Files moved from interp-core and interpfcn directories. * libinterp/interp-core/Cell.cc, libinterp/interp-core/Cell.h, libinterp/interp-core/action-container.h, libinterp/interp-core/c-file-ptr-stream.cc, libinterp/interp-core/c-file-ptr-stream.h, libinterp/interp-core/comment-list.cc, libinterp/interp-core/comment-list.h, libinterp/interp-core/cutils.c, libinterp/interp-core/cutils.h, libinterp/interp-core/defun-dld.h, libinterp/interp-core/defun-int.h, libinterp/interp-core/display.cc, libinterp/interp-core/display.h, libinterp/interp-core/dynamic-ld.cc, libinterp/interp-core/dynamic-ld.h, libinterp/interp-core/event-queue.h, libinterp/interp-core/gl-render.cc, libinterp/interp-core/gl-render.h, libinterp/interp-core/gl2ps-renderer.cc, libinterp/interp-core/gl2ps-renderer.h, libinterp/interp-core/gl2ps.c, libinterp/interp-core/gl2ps.h, libinterp/interp-core/gripes.cc, libinterp/interp-core/gripes.h, libinterp/interp-core/jit-ir.cc, libinterp/interp-core/jit-ir.h, libinterp/interp-core/jit-typeinfo.cc, libinterp/interp-core/jit-typeinfo.h, libinterp/interp-core/jit-util.cc, libinterp/interp-core/jit-util.h, libinterp/interp-core/ls-ascii-helper.cc, libinterp/interp-core/ls-ascii-helper.h, libinterp/interp-core/ls-hdf5.cc, libinterp/interp-core/ls-hdf5.h, libinterp/interp-core/ls-mat-ascii.cc, libinterp/interp-core/ls-mat-ascii.h, libinterp/interp-core/ls-mat4.cc, libinterp/interp-core/ls-mat4.h, libinterp/interp-core/ls-mat5.cc, libinterp/interp-core/ls-mat5.h, libinterp/interp-core/ls-oct-binary.cc, libinterp/interp-core/ls-oct-binary.h, libinterp/interp-core/ls-utils.cc, libinterp/interp-core/ls-utils.h, libinterp/interp-core/matherr.c, libinterp/interp-core/mex.cc, libinterp/interp-core/mex.h, libinterp/interp-core/mexproto.h, libinterp/interp-core/module.mk, libinterp/interp-core/mxarray.in.h, libinterp/interp-core/oct-errno.h, libinterp/interp-core/oct-errno.in.cc, libinterp/interp-core/oct-fstrm.cc, libinterp/interp-core/oct-fstrm.h, libinterp/interp-core/oct-hdf5.h, libinterp/interp-core/oct-iostrm.cc, libinterp/interp-core/oct-iostrm.h, libinterp/interp-core/oct-lvalue.cc, libinterp/interp-core/oct-lvalue.h, libinterp/interp-core/oct-map.cc, libinterp/interp-core/oct-map.h, libinterp/interp-core/oct-obj.cc, libinterp/interp-core/oct-obj.h, libinterp/interp-core/oct-prcstrm.cc, libinterp/interp-core/oct-prcstrm.h, libinterp/interp-core/oct-procbuf.cc, libinterp/interp-core/oct-procbuf.h, libinterp/interp-core/oct-stdstrm.h, libinterp/interp-core/oct-stream.cc, libinterp/interp-core/oct-stream.h, libinterp/interp-core/oct-strstrm.cc, libinterp/interp-core/oct-strstrm.h, libinterp/interp-core/oct.h, libinterp/interp-core/procstream.cc, libinterp/interp-core/procstream.h, libinterp/interp-core/pt-jit.cc, libinterp/interp-core/pt-jit.h, libinterp/interp-core/siglist.c, libinterp/interp-core/siglist.h, libinterp/interp-core/sparse-xdiv.cc, libinterp/interp-core/sparse-xdiv.h, libinterp/interp-core/sparse-xpow.cc, libinterp/interp-core/sparse-xpow.h, libinterp/interp-core/txt-eng-ft.cc, libinterp/interp-core/txt-eng-ft.h, libinterp/interp-core/txt-eng.h, libinterp/interp-core/unwind-prot.cc, libinterp/interp-core/unwind-prot.h, libinterp/interp-core/xdiv.cc, libinterp/interp-core/xdiv.h, libinterp/interp-core/xgl2ps.c, libinterp/interp-core/xnorm.cc, libinterp/interp-core/xnorm.h, libinterp/interp-core/xpow.cc, libinterp/interp-core/xpow.h, libinterp/interp-core/zfstream.cc, libinterp/interp-core/zfstream.h, libinterp/interpfcn/data.cc, libinterp/interpfcn/data.h, libinterp/interpfcn/debug.cc, libinterp/interpfcn/debug.h, libinterp/interpfcn/defaults.cc, libinterp/interpfcn/defaults.in.h, libinterp/interpfcn/defun.cc, libinterp/interpfcn/defun.h, libinterp/interpfcn/dirfns.cc, libinterp/interpfcn/dirfns.h, libinterp/interpfcn/error.cc, libinterp/interpfcn/error.h, libinterp/interpfcn/file-io.cc, libinterp/interpfcn/file-io.h, libinterp/interpfcn/graphics.cc, libinterp/interpfcn/graphics.in.h, libinterp/interpfcn/help.cc, libinterp/interpfcn/help.h, libinterp/interpfcn/hook-fcn.cc, libinterp/interpfcn/hook-fcn.h, libinterp/interpfcn/input.cc, libinterp/interpfcn/input.h, libinterp/interpfcn/load-path.cc, libinterp/interpfcn/load-path.h, libinterp/interpfcn/load-save.cc, libinterp/interpfcn/load-save.h, libinterp/interpfcn/ls-oct-ascii.cc, libinterp/interpfcn/ls-oct-ascii.h, libinterp/interpfcn/module.mk, libinterp/interpfcn/oct-hist.cc, libinterp/interpfcn/oct-hist.h, libinterp/interpfcn/octave-link.cc, libinterp/interpfcn/octave-link.h, libinterp/interpfcn/pager.cc, libinterp/interpfcn/pager.h, libinterp/interpfcn/pr-output.cc, libinterp/interpfcn/pr-output.h, libinterp/interpfcn/profiler.cc, libinterp/interpfcn/profiler.h, libinterp/interpfcn/sighandlers.cc, libinterp/interpfcn/sighandlers.h, libinterp/interpfcn/symtab.cc, libinterp/interpfcn/symtab.h, libinterp/interpfcn/sysdep.cc, libinterp/interpfcn/sysdep.h, libinterp/interpfcn/toplev.cc, libinterp/interpfcn/toplev.h, libinterp/interpfcn/utils.cc, libinterp/interpfcn/utils.h, libinterp/interpfcn/variables.cc, libinterp/interpfcn/variables.h, libinterp/interpfcn/workspace-element.h: deleted files.
author Rik <rik@octave.org>
date Wed, 03 Jul 2013 17:43:48 -0700
parents libinterp/interpfcn/pr-output.cc@0c340bf413d7
children 259c1f295a1e
comparison
equal deleted inserted replaced
16891:486c3e2731ff 16892:68fc671a9339
1 /*
2
3 Copyright (C) 1993-2012 John W. Eaton
4
5 This file is part of Octave.
6
7 Octave is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by the
9 Free Software Foundation; either version 3 of the License, or (at your
10 option) any later version.
11
12 Octave is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with Octave; see the file COPYING. If not, see
19 <http://www.gnu.org/licenses/>.
20
21 */
22
23 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif
26
27 #include <cfloat>
28 #include <cstdio>
29 #include <cstring>
30
31 #include <iomanip>
32 #include <iostream>
33 #include <sstream>
34 #include <string>
35
36 #include "Array-util.h"
37 #include "CMatrix.h"
38 #include "Range.h"
39 #include "cmd-edit.h"
40 #include "dMatrix.h"
41 #include "lo-mappers.h"
42 #include "lo-math.h"
43 #include "mach-info.h"
44 #include "oct-cmplx.h"
45 #include "quit.h"
46 #include "str-vec.h"
47
48 #include "Cell.h"
49 #include "defun.h"
50 #include "error.h"
51 #include "gripes.h"
52 #include "oct-obj.h"
53 #include "oct-stream.h"
54 #include "pager.h"
55 #include "pr-output.h"
56 #include "sysdep.h"
57 #include "unwind-prot.h"
58 #include "utils.h"
59 #include "variables.h"
60
61 // TRUE means use a scaled fixed point format for 'format long' and
62 // 'format short'.
63 static bool Vfixed_point_format = false;
64
65 // The maximum field width for a number printed by the default output
66 // routines.
67 static int Voutput_max_field_width = 10;
68
69 // The precision of the numbers printed by the default output
70 // routines.
71 static int Voutput_precision = 5;
72
73 // TRUE means that the dimensions of empty objects should be printed
74 // like this: x = [](2x0).
75 bool Vprint_empty_dimensions = true;
76
77 // TRUE means that the rows of big matrices should be split into
78 // smaller slices that fit on the screen.
79 static bool Vsplit_long_rows = true;
80
81 // TRUE means don't do any fancy formatting.
82 static bool free_format = false;
83
84 // TRUE means print plus sign for nonzero, blank for zero.
85 static bool plus_format = false;
86
87 // First char for > 0, second for < 0, third for == 0.
88 static std::string plus_format_chars = "+ ";
89
90 // TRUE means always print in a rational approximation
91 static bool rat_format = false;
92
93 // Used to force the length of the rational approximation string for Frats
94 static int rat_string_len = -1;
95
96 // TRUE means always print like dollars and cents.
97 static bool bank_format = false;
98
99 // TRUE means print data in hexadecimal format.
100 static int hex_format = 0;
101
102 // TRUE means print data in binary-bit-pattern format.
103 static int bit_format = 0;
104
105 // TRUE means don't put newlines around the column number headers.
106 bool Vcompact_format = false;
107
108 // TRUE means use an e format.
109 static bool print_e = false;
110
111 // TRUE means use a g format.
112 static bool print_g = false;
113
114 // TRUE means print E instead of e for exponent field.
115 static bool print_big_e = false;
116
117 // TRUE means use an engineering format.
118 static bool print_eng = false;
119
120 class pr_engineering_float;
121 class pr_formatted_float;
122 class pr_rational_float;
123
124 static int
125 current_output_max_field_width (void)
126 {
127 return Voutput_max_field_width;
128 }
129
130 static int
131 current_output_precision (void)
132 {
133 return Voutput_precision;
134 }
135
136 class
137 float_format
138 {
139 public:
140
141 float_format (int w = current_output_max_field_width (),
142 int p = current_output_precision (), int f = 0)
143 : fw (w), ex (0), prec (p), fmt (f), up (0), sp (0) { }
144
145 float_format (int w, int e, int p, int f)
146 : fw (w), ex (e), prec (p), fmt (f), up (0), sp (0) { }
147
148 float_format (const float_format& ff)
149 : fw (ff.fw), ex (ff.ex), prec (ff.prec), fmt (ff.fmt), up (ff.up), sp (ff.sp) { }
150
151 float_format& operator = (const float_format& ff)
152 {
153 if (&ff != this)
154 {
155 fw = ff.fw;
156 ex = ff.ex;
157 prec = ff.prec;
158 fmt = ff.fmt;
159 up = ff.up;
160 sp = ff.sp;
161 }
162
163 return *this;
164 }
165
166 ~float_format (void) { }
167
168 float_format& scientific (void) { fmt = std::ios::scientific; return *this; }
169 float_format& fixed (void) { fmt = std::ios::fixed; return *this; }
170 float_format& general (void) { fmt = 0; return *this; }
171
172 float_format& uppercase (void) { up = std::ios::uppercase; return *this; }
173 float_format& lowercase (void) { up = 0; return *this; }
174
175 float_format& precision (int p) { prec = p; return *this; }
176
177 float_format& width (int w) { fw = w; return *this; }
178
179 float_format& trailing_zeros (bool tz = true)
180 { sp = tz ? std::ios::showpoint : 0; return *this; }
181
182 friend std::ostream& operator << (std::ostream& os,
183 const pr_engineering_float& pef);
184
185 friend std::ostream& operator << (std::ostream& os,
186 const pr_formatted_float& pff);
187
188 friend std::ostream& operator << (std::ostream& os,
189 const pr_rational_float& prf);
190
191 private:
192
193 // Field width. Zero means as wide as necessary.
194 int fw;
195
196 // Exponent Field width. Zero means as wide as necessary.
197 int ex;
198
199 // Precision.
200 int prec;
201
202 // Format.
203 int fmt;
204
205 // E or e.
206 int up;
207
208 // Show trailing zeros.
209 int sp;
210 };
211
212 static int
213 calc_scale_exp (const int& x)
214 {
215 if (! print_eng)
216 return x;
217 else
218 return x - 3*static_cast<int> (x/3);
219 /* The expression above is equivalent to x - (x % 3).
220 * According to the ISO specification for C++ the modulo operator is
221 * compiler dependent if any of the arguments are negative. Since this
222 * function will need to work on negative arguments, and we want to avoid
223 * portability issues, we re-implement the modulo function to the desired
224 * behavior (truncation). There may be a gnulib replacement.
225 *
226 * ISO/IEC 14882:2003 : Programming languages -- C++. 5.6.4: ISO, IEC. 2003 .
227 * "the binary % operator yields the remainder from the division of the first
228 * expression by the second. .... If both operands are nonnegative then the
229 * remainder is nonnegative; if not, the sign of the remainder is
230 * implementation-defined". */
231 }
232
233 static int
234 engineering_exponent (const double& x)
235 {
236 int ex = 0;
237 if (x != 0)
238 {
239 double absval = (x < 0.0 ? -x : x);
240 int logabsval = static_cast<int> (gnulib::floor (log10 (absval)));
241 /* Avoid using modulo function with negative arguments for portability.
242 * See extended comment at calc_scale_exp */
243 if (logabsval < 0.0)
244 ex = logabsval - 2 + ((-logabsval + 2) % 3);
245 else
246 ex = logabsval - (logabsval % 3);
247 }
248 return ex;
249 }
250
251 static int
252 num_digits (const double& x)
253 {
254 return 1 + (print_eng
255 ? engineering_exponent (x)
256 : static_cast<int> (gnulib::floor (log10 (x))));
257 }
258
259 class
260 pr_engineering_float
261 {
262 public:
263
264 const float_format& f;
265
266 double val;
267
268 int exponent (void) const
269 {
270 return engineering_exponent (val);
271 }
272
273 double mantissa (void) const
274 {
275 return val / std::pow (10.0, exponent ());
276 }
277
278 pr_engineering_float (const float_format& f_arg, double val_arg)
279 : f (f_arg), val (val_arg) { }
280 };
281
282 std::ostream&
283 operator << (std::ostream& os, const pr_engineering_float& pef)
284 {
285 if (pef.f.fw >= 0)
286 os << std::setw (pef.f.fw - pef.f.ex);
287
288 if (pef.f.prec >= 0)
289 os << std::setprecision (pef.f.prec);
290
291 std::ios::fmtflags oflags =
292 os.flags (static_cast<std::ios::fmtflags>
293 (pef.f.fmt | pef.f.up | pef.f.sp));
294
295 os << pef.mantissa ();
296
297 int ex = pef.exponent ();
298 if (ex < 0)
299 {
300 os << std::setw (0) << "e-";
301 ex = -ex;
302 }
303 else
304 os << std::setw (0) << "e+";
305
306 os << std::setw (pef.f.ex - 2) << std::setfill ('0') << ex
307 << std::setfill (' ');
308
309 os.flags (oflags);
310
311 return os;
312 }
313
314 class
315 pr_formatted_float
316 {
317 public:
318
319 const float_format& f;
320
321 double val;
322
323 pr_formatted_float (const float_format& f_arg, double val_arg)
324 : f (f_arg), val (val_arg) { }
325 };
326
327 std::ostream&
328 operator << (std::ostream& os, const pr_formatted_float& pff)
329 {
330 if (pff.f.fw >= 0)
331 os << std::setw (pff.f.fw);
332
333 if (pff.f.prec >= 0)
334 os << std::setprecision (pff.f.prec);
335
336 std::ios::fmtflags oflags =
337 os.flags (static_cast<std::ios::fmtflags>
338 (pff.f.fmt | pff.f.up | pff.f.sp));
339
340 os << pff.val;
341
342 os.flags (oflags);
343
344 return os;
345 }
346
347 static inline std::string
348 rational_approx (double val, int len)
349 {
350 std::string s;
351
352 if (len <= 0)
353 len = 10;
354
355 if (xisinf (val))
356 s = "1/0";
357 else if (xisnan (val))
358 s = "0/0";
359 else if (val < std::numeric_limits<int>::min ()
360 || val > std::numeric_limits<int>::max ()
361 || D_NINT (val) == val)
362 {
363 std::ostringstream buf;
364 buf.flags (std::ios::fixed);
365 buf << std::setprecision (0) << xround (val);
366 s = buf.str ();
367 }
368 else
369 {
370 double lastn = 1.;
371 double lastd = 0.;
372 double n = xround (val);
373 double d = 1.;
374 double frac = val - n;
375 int m = 0;
376
377 std::ostringstream buf2;
378 buf2.flags (std::ios::fixed);
379 buf2 << std::setprecision (0) << static_cast<int>(n);
380 s = buf2.str ();
381
382 while (1)
383 {
384 double flip = 1. / frac;
385 double step = xround (flip);
386 double nextn = n;
387 double nextd = d;
388
389 // Have we converged to 1/intmax ?
390 if (m > 100 || fabs (frac) < 1 / static_cast<double> (std::numeric_limits<int>::max ()))
391 {
392 lastn = n;
393 lastd = d;
394 break;
395 }
396
397 frac = flip - step;
398 n = n * step + lastn;
399 d = d * step + lastd;
400 lastn = nextn;
401 lastd = nextd;
402
403 std::ostringstream buf;
404 buf.flags (std::ios::fixed);
405 buf << std::setprecision (0) << static_cast<int>(n)
406 << "/" << static_cast<int>(d);
407 m++;
408
409 if (n < 0 && d < 0)
410 {
411 // Double negative, string can be two characters longer..
412 if (buf.str ().length () > static_cast<unsigned int>(len + 2) &&
413 m > 1)
414 break;
415 }
416 else if (buf.str ().length () > static_cast<unsigned int>(len) &&
417 m > 1)
418 break;
419
420 s = buf.str ();
421 }
422
423 if (lastd < 0.)
424 {
425 // Move sign to the top
426 lastd = - lastd;
427 lastn = - lastn;
428 std::ostringstream buf;
429 buf.flags (std::ios::fixed);
430 buf << std::setprecision (0) << static_cast<int>(lastn)
431 << "/" << static_cast<int>(lastd);
432 s = buf.str ();
433 }
434 }
435
436 return s;
437 }
438
439 class
440 pr_rational_float
441 {
442 public:
443
444 const float_format& f;
445
446 double val;
447
448 pr_rational_float (const float_format& f_arg, double val_arg)
449 : f (f_arg), val (val_arg) { }
450 };
451
452 std::ostream&
453 operator << (std::ostream& os, const pr_rational_float& prf)
454 {
455 int fw = (rat_string_len > 0 ? rat_string_len : prf.f.fw);
456 std::string s = rational_approx (prf.val, fw);
457
458 if (fw >= 0)
459 os << std::setw (fw);
460
461 std::ios::fmtflags oflags =
462 os.flags (static_cast<std::ios::fmtflags>
463 (prf.f.fmt | prf.f.up | prf.f.sp));
464
465 if (fw > 0 && s.length () > static_cast<unsigned int>(fw))
466 os << "*";
467 else
468 os << s;
469
470 os.flags (oflags);
471
472 return os;
473 }
474
475 // Current format for real numbers and the real part of complex
476 // numbers.
477 static float_format *curr_real_fmt = 0;
478
479 // Current format for the imaginary part of complex numbers.
480 static float_format *curr_imag_fmt = 0;
481
482 static double
483 pr_max_internal (const Matrix& m)
484 {
485 octave_idx_type nr = m.rows ();
486 octave_idx_type nc = m.columns ();
487
488 double result = -std::numeric_limits<double>::max ();
489
490 bool all_inf_or_nan = true;
491
492 for (octave_idx_type j = 0; j < nc; j++)
493 for (octave_idx_type i = 0; i < nr; i++)
494 {
495 double val = m(i,j);
496 if (xisinf (val) || xisnan (val))
497 continue;
498
499 all_inf_or_nan = false;
500
501 if (val > result)
502 result = val;
503 }
504
505 if (all_inf_or_nan)
506 result = 0.0;
507
508 return result;
509 }
510
511 static double
512 pr_min_internal (const Matrix& m)
513 {
514 octave_idx_type nr = m.rows ();
515 octave_idx_type nc = m.columns ();
516
517 double result = std::numeric_limits<double>::max ();
518
519 bool all_inf_or_nan = true;
520
521 for (octave_idx_type j = 0; j < nc; j++)
522 for (octave_idx_type i = 0; i < nr; i++)
523 {
524 double val = m(i,j);
525 if (xisinf (val) || xisnan (val))
526 continue;
527
528 all_inf_or_nan = false;
529
530 if (val < result)
531 result = val;
532 }
533
534 if (all_inf_or_nan)
535 result = 0.0;
536
537 return result;
538 }
539
540 // FIXME -- it would be nice to share more code among these
541 // functions,..
542
543 static void
544 set_real_format (int digits, bool inf_or_nan, bool int_only, int &fw)
545 {
546 static float_format fmt;
547
548 int prec = Voutput_precision;
549
550 int ld, rd;
551
552 if (rat_format)
553 {
554 fw = 0;
555 rd = 0;
556 }
557 else if (bank_format)
558 {
559 fw = digits < 0 ? 4 : digits + 3;
560 if (inf_or_nan && fw < 4)
561 fw = 4;
562 rd = 2;
563 }
564 else if (hex_format)
565 {
566 fw = 2 * sizeof (double);
567 rd = 0;
568 }
569 else if (bit_format)
570 {
571 fw = 8 * sizeof (double);
572 rd = 0;
573 }
574 else if (inf_or_nan || int_only)
575 {
576 fw = 1 + digits;
577 if (inf_or_nan && fw < 4)
578 fw = 4;
579 rd = fw;
580 }
581 else
582 {
583 if (digits > 0)
584 {
585 ld = digits;
586 rd = prec > digits ? prec - digits : prec;
587 digits++;
588 }
589 else
590 {
591 ld = 1;
592 rd = prec > digits ? prec - digits : prec;
593 digits = -digits + 1;
594 }
595
596 fw = 1 + ld + 1 + rd;
597 if (inf_or_nan && fw < 4)
598 fw = 4;
599 }
600
601 if (! (rat_format || bank_format || hex_format || bit_format)
602 && (fw > Voutput_max_field_width || print_e || print_g || print_eng))
603 {
604 if (print_g)
605 fmt = float_format ();
606 else
607 {
608 // e+ddd
609 int ex = 5;
610
611 if (print_eng)
612 {
613 // -ddd.
614 fw = 5 + prec + ex;
615 if (inf_or_nan && fw < 6)
616 fw = 6;
617 fmt = float_format (fw, ex, prec - 1, std::ios::fixed);
618 }
619 else
620 {
621 // -d.
622 fw = 3 + prec + ex;
623 if (inf_or_nan && fw < 4)
624 fw = 4;
625 fmt = float_format (fw, ex, prec - 1, std::ios::scientific);
626 }
627 }
628
629 if (print_big_e)
630 fmt.uppercase ();
631 }
632 else if (! bank_format && (inf_or_nan || int_only))
633 fmt = float_format (fw, rd);
634 else
635 fmt = float_format (fw, rd, std::ios::fixed);
636
637 curr_real_fmt = &fmt;
638 }
639
640 static void
641 set_format (double d, int& fw)
642 {
643 curr_real_fmt = 0;
644 curr_imag_fmt = 0;
645
646 if (free_format)
647 return;
648
649 bool inf_or_nan = (xisinf (d) || xisnan (d));
650
651 bool int_only = (! inf_or_nan && D_NINT (d) == d);
652
653 double d_abs = d < 0.0 ? -d : d;
654
655 int digits = (inf_or_nan || d_abs == 0.0)
656 ? 0 : num_digits (d_abs);
657
658 set_real_format (digits, inf_or_nan, int_only, fw);
659 }
660
661 static inline void
662 set_format (double d)
663 {
664 int fw;
665 set_format (d, fw);
666 }
667
668 static void
669 set_real_matrix_format (int x_max, int x_min, bool inf_or_nan,
670 int int_or_inf_or_nan, int& fw)
671 {
672 static float_format fmt;
673
674 int prec = Voutput_precision;
675
676 int ld, rd;
677
678 if (rat_format)
679 {
680 fw = 9;
681 rd = 0;
682 }
683 else if (bank_format)
684 {
685 int digits = x_max > x_min ? x_max : x_min;
686 fw = digits <= 0 ? 4 : digits + 3;
687 if (inf_or_nan && fw < 4)
688 fw = 4;
689 rd = 2;
690 }
691 else if (hex_format)
692 {
693 fw = 2 * sizeof (double);
694 rd = 0;
695 }
696 else if (bit_format)
697 {
698 fw = 8 * sizeof (double);
699 rd = 0;
700 }
701 else if (Vfixed_point_format && ! print_g)
702 {
703 rd = prec;
704 fw = rd + 2;
705 if (inf_or_nan && fw < 4)
706 fw = 4;
707 }
708 else if (int_or_inf_or_nan)
709 {
710 int digits = x_max > x_min ? x_max : x_min;
711 fw = digits <= 0 ? 2 : digits + 1;
712 if (inf_or_nan && fw < 4)
713 fw = 4;
714 rd = fw;
715 }
716 else
717 {
718 int ld_max, rd_max;
719 if (x_max > 0)
720 {
721 ld_max = x_max;
722 rd_max = prec > x_max ? prec - x_max : prec;
723 x_max++;
724 }
725 else
726 {
727 ld_max = 1;
728 rd_max = prec > x_max ? prec - x_max : prec;
729 x_max = -x_max + 1;
730 }
731
732 int ld_min, rd_min;
733 if (x_min > 0)
734 {
735 ld_min = x_min;
736 rd_min = prec > x_min ? prec - x_min : prec;
737 x_min++;
738 }
739 else
740 {
741 ld_min = 1;
742 rd_min = prec > x_min ? prec - x_min : prec;
743 x_min = -x_min + 1;
744 }
745
746 ld = ld_max > ld_min ? ld_max : ld_min;
747 rd = rd_max > rd_min ? rd_max : rd_min;
748
749 fw = 1 + ld + 1 + rd;
750 if (inf_or_nan && fw < 4)
751 fw = 4;
752 }
753
754 if (! (rat_format || bank_format || hex_format || bit_format)
755 && (print_e
756 || print_eng || print_g
757 || (! Vfixed_point_format && fw > Voutput_max_field_width)))
758 {
759 if (print_g)
760 fmt = float_format ();
761 else
762 {
763 int ex = 4;
764 if (x_max > 100 || x_min > 100)
765 ex++;
766
767 if (print_eng)
768 {
769 fw = 4 + prec + ex;
770 if (inf_or_nan && fw < 6)
771 fw = 6;
772 fmt = float_format (fw, ex, prec - 1, std::ios::fixed);
773 }
774 else
775 {
776 fw = 2 + prec + ex;
777 if (inf_or_nan && fw < 4)
778 fw = 4;
779 fmt = float_format (fw, prec - 1, std::ios::scientific);
780 }
781 }
782
783 if (print_big_e)
784 fmt.uppercase ();
785 }
786 else if (! bank_format && int_or_inf_or_nan)
787 fmt = float_format (fw, rd);
788 else
789 fmt = float_format (fw, rd, std::ios::fixed);
790
791 curr_real_fmt = &fmt;
792 }
793
794 static void
795 set_format (const Matrix& m, int& fw, double& scale)
796 {
797 curr_real_fmt = 0;
798 curr_imag_fmt = 0;
799
800 if (free_format)
801 return;
802
803 bool inf_or_nan = m.any_element_is_inf_or_nan ();
804
805 bool int_or_inf_or_nan = m.all_elements_are_int_or_inf_or_nan ();
806
807 Matrix m_abs = m.abs ();
808 double max_abs = pr_max_internal (m_abs);
809 double min_abs = pr_min_internal (m_abs);
810
811 int x_max = max_abs == 0.0 ? 0 : num_digits (max_abs);
812
813 int x_min = min_abs == 0.0 ? 0 : num_digits (min_abs);
814
815 scale = (x_max == 0 || int_or_inf_or_nan) ? 1.0
816 : std::pow (10.0, calc_scale_exp (x_max - 1));
817
818 set_real_matrix_format (x_max, x_min, inf_or_nan, int_or_inf_or_nan, fw);
819 }
820
821 static inline void
822 set_format (const Matrix& m)
823 {
824 int fw;
825 double scale;
826 set_format (m, fw, scale);
827 }
828
829 static void
830 set_complex_format (int x_max, int x_min, int r_x, bool inf_or_nan,
831 int int_only, int& r_fw, int& i_fw)
832 {
833 static float_format r_fmt;
834 static float_format i_fmt;
835
836 int prec = Voutput_precision;
837
838 int ld, rd;
839
840 if (rat_format)
841 {
842 i_fw = 0;
843 r_fw = 0;
844 rd = 0;
845 }
846 else if (bank_format)
847 {
848 int digits = r_x;
849 i_fw = 0;
850 r_fw = digits <= 0 ? 4 : digits + 3;
851 if (inf_or_nan && r_fw < 4)
852 r_fw = 4;
853 rd = 2;
854 }
855 else if (hex_format)
856 {
857 r_fw = 2 * sizeof (double);
858 i_fw = 2 * sizeof (double);
859 rd = 0;
860 }
861 else if (bit_format)
862 {
863 r_fw = 8 * sizeof (double);
864 i_fw = 8 * sizeof (double);
865 rd = 0;
866 }
867 else if (inf_or_nan || int_only)
868 {
869 int digits = x_max > x_min ? x_max : x_min;
870 i_fw = digits <= 0 ? 1 : digits;
871 r_fw = i_fw + 1;
872 if (inf_or_nan && i_fw < 3)
873 {
874 i_fw = 3;
875 r_fw = 4;
876 }
877 rd = r_fw;
878 }
879 else
880 {
881 int ld_max, rd_max;
882 if (x_max > 0)
883 {
884 ld_max = x_max;
885 rd_max = prec > x_max ? prec - x_max : prec;
886 x_max++;
887 }
888 else
889 {
890 ld_max = 1;
891 rd_max = prec > x_max ? prec - x_max : prec;
892 x_max = -x_max + 1;
893 }
894
895 int ld_min, rd_min;
896 if (x_min > 0)
897 {
898 ld_min = x_min;
899 rd_min = prec > x_min ? prec - x_min : prec;
900 x_min++;
901 }
902 else
903 {
904 ld_min = 1;
905 rd_min = prec > x_min ? prec - x_min : prec;
906 x_min = -x_min + 1;
907 }
908
909 ld = ld_max > ld_min ? ld_max : ld_min;
910 rd = rd_max > rd_min ? rd_max : rd_min;
911
912 i_fw = ld + 1 + rd;
913 r_fw = i_fw + 1;
914 if (inf_or_nan && i_fw < 3)
915 {
916 i_fw = 3;
917 r_fw = 4;
918 }
919 }
920
921 if (! (rat_format || bank_format || hex_format || bit_format)
922 && (r_fw > Voutput_max_field_width || print_e || print_eng || print_g))
923 {
924 if (print_g)
925 {
926 r_fmt = float_format ();
927 i_fmt = float_format ();
928 }
929 else
930 {
931 int ex = 4;
932 if (x_max > 100 || x_min > 100)
933 ex++;
934
935 if (print_eng)
936 {
937 i_fw = 3 + prec + ex;
938 r_fw = i_fw + 1;
939 if (inf_or_nan && i_fw < 5)
940 {
941 i_fw = 5;
942 r_fw = 6;
943 }
944 r_fmt = float_format (r_fw, ex, prec - 1, std::ios::fixed);
945 i_fmt = float_format (i_fw, ex, prec - 1, std::ios::fixed);
946 }
947 else
948 {
949 i_fw = 1 + prec + ex;
950 r_fw = i_fw + 1;
951 if (inf_or_nan && i_fw < 3)
952 {
953 i_fw = 3;
954 r_fw = 4;
955 }
956 r_fmt = float_format (r_fw, prec - 1, std::ios::scientific);
957 i_fmt = float_format (i_fw, prec - 1, std::ios::scientific);
958 }
959 }
960
961 if (print_big_e)
962 {
963 r_fmt.uppercase ();
964 i_fmt.uppercase ();
965 }
966 }
967 else if (! bank_format && (inf_or_nan || int_only))
968 {
969 r_fmt = float_format (r_fw, rd);
970 i_fmt = float_format (i_fw, rd);
971 }
972 else
973 {
974 r_fmt = float_format (r_fw, rd, std::ios::fixed);
975 i_fmt = float_format (i_fw, rd, std::ios::fixed);
976 }
977
978 curr_real_fmt = &r_fmt;
979 curr_imag_fmt = &i_fmt;
980 }
981
982 static void
983 set_format (const Complex& c, int& r_fw, int& i_fw)
984 {
985 curr_real_fmt = 0;
986 curr_imag_fmt = 0;
987
988 if (free_format)
989 return;
990
991 double rp = c.real ();
992 double ip = c.imag ();
993
994 bool inf_or_nan = (xisinf (c) || xisnan (c));
995
996 bool int_only = (D_NINT (rp) == rp && D_NINT (ip) == ip);
997
998 double r_abs = rp < 0.0 ? -rp : rp;
999 double i_abs = ip < 0.0 ? -ip : ip;
1000
1001 int r_x = (xisinf (rp) || xisnan (rp) || r_abs == 0.0)
1002 ? 0 : num_digits (r_abs);
1003
1004 int i_x = (xisinf (ip) || xisnan (ip) || i_abs == 0.0)
1005 ? 0 : num_digits (i_abs);
1006
1007 int x_max, x_min;
1008
1009 if (r_x > i_x)
1010 {
1011 x_max = r_x;
1012 x_min = i_x;
1013 }
1014 else
1015 {
1016 x_max = i_x;
1017 x_min = r_x;
1018 }
1019
1020 set_complex_format (x_max, x_min, r_x, inf_or_nan, int_only, r_fw, i_fw);
1021 }
1022
1023 static inline void
1024 set_format (const Complex& c)
1025 {
1026 int r_fw, i_fw;
1027 set_format (c, r_fw, i_fw);
1028 }
1029
1030 static void
1031 set_complex_matrix_format (int x_max, int x_min, int r_x_max,
1032 int r_x_min, bool inf_or_nan,
1033 int int_or_inf_or_nan, int& r_fw, int& i_fw)
1034 {
1035 static float_format r_fmt;
1036 static float_format i_fmt;
1037
1038 int prec = Voutput_precision;
1039
1040 int ld, rd;
1041
1042 if (rat_format)
1043 {
1044 i_fw = 9;
1045 r_fw = 9;
1046 rd = 0;
1047 }
1048 else if (bank_format)
1049 {
1050 int digits = r_x_max > r_x_min ? r_x_max : r_x_min;
1051 i_fw = 0;
1052 r_fw = digits <= 0 ? 4 : digits + 3;
1053 if (inf_or_nan && r_fw < 4)
1054 r_fw = 4;
1055 rd = 2;
1056 }
1057 else if (hex_format)
1058 {
1059 r_fw = 2 * sizeof (double);
1060 i_fw = 2 * sizeof (double);
1061 rd = 0;
1062 }
1063 else if (bit_format)
1064 {
1065 r_fw = 8 * sizeof (double);
1066 i_fw = 8 * sizeof (double);
1067 rd = 0;
1068 }
1069 else if (Vfixed_point_format && ! print_g)
1070 {
1071 rd = prec;
1072 i_fw = rd + 1;
1073 r_fw = i_fw + 1;
1074 if (inf_or_nan && i_fw < 3)
1075 {
1076 i_fw = 3;
1077 r_fw = 4;
1078 }
1079 }
1080 else if (int_or_inf_or_nan)
1081 {
1082 int digits = x_max > x_min ? x_max : x_min;
1083 i_fw = digits <= 0 ? 1 : digits;
1084 r_fw = i_fw + 1;
1085 if (inf_or_nan && i_fw < 3)
1086 {
1087 i_fw = 3;
1088 r_fw = 4;
1089 }
1090 rd = r_fw;
1091 }
1092 else
1093 {
1094 int ld_max, rd_max;
1095 if (x_max > 0)
1096 {
1097 ld_max = x_max;
1098 rd_max = prec > x_max ? prec - x_max : prec;
1099 x_max++;
1100 }
1101 else
1102 {
1103 ld_max = 1;
1104 rd_max = prec > x_max ? prec - x_max : prec;
1105 x_max = -x_max + 1;
1106 }
1107
1108 int ld_min, rd_min;
1109 if (x_min > 0)
1110 {
1111 ld_min = x_min;
1112 rd_min = prec > x_min ? prec - x_min : prec;
1113 x_min++;
1114 }
1115 else
1116 {
1117 ld_min = 1;
1118 rd_min = prec > x_min ? prec - x_min : prec;
1119 x_min = -x_min + 1;
1120 }
1121
1122 ld = ld_max > ld_min ? ld_max : ld_min;
1123 rd = rd_max > rd_min ? rd_max : rd_min;
1124
1125 i_fw = ld + 1 + rd;
1126 r_fw = i_fw + 1;
1127 if (inf_or_nan && i_fw < 3)
1128 {
1129 i_fw = 3;
1130 r_fw = 4;
1131 }
1132 }
1133
1134 if (! (rat_format || bank_format || hex_format || bit_format)
1135 && (print_e
1136 || print_eng || print_g
1137 || (! Vfixed_point_format && r_fw > Voutput_max_field_width)))
1138 {
1139 if (print_g)
1140 {
1141 r_fmt = float_format ();
1142 i_fmt = float_format ();
1143 }
1144 else
1145 {
1146 int ex = 4;
1147 if (x_max > 100 || x_min > 100)
1148 ex++;
1149
1150 if (print_eng)
1151 {
1152 i_fw = 3 + prec + ex;
1153 r_fw = i_fw + 1;
1154 if (inf_or_nan && i_fw < 5)
1155 {
1156 i_fw = 5;
1157 r_fw = 6;
1158 }
1159 r_fmt = float_format (r_fw, ex, prec - 1, std::ios::fixed);
1160 i_fmt = float_format (i_fw, ex, prec - 1, std::ios::fixed);
1161 }
1162 else
1163 {
1164 i_fw = 1 + prec + ex;
1165 r_fw = i_fw + 1;
1166 if (inf_or_nan && i_fw < 3)
1167 {
1168 i_fw = 3;
1169 r_fw = 4;
1170 }
1171 r_fmt = float_format (r_fw, prec - 1, std::ios::scientific);
1172 i_fmt = float_format (i_fw, prec - 1, std::ios::scientific);
1173 }
1174 }
1175
1176 if (print_big_e)
1177 {
1178 r_fmt.uppercase ();
1179 i_fmt.uppercase ();
1180 }
1181 }
1182 else if (! bank_format && int_or_inf_or_nan)
1183 {
1184 r_fmt = float_format (r_fw, rd);
1185 i_fmt = float_format (i_fw, rd);
1186 }
1187 else
1188 {
1189 r_fmt = float_format (r_fw, rd, std::ios::fixed);
1190 i_fmt = float_format (i_fw, rd, std::ios::fixed);
1191 }
1192
1193 curr_real_fmt = &r_fmt;
1194 curr_imag_fmt = &i_fmt;
1195 }
1196
1197 static void
1198 set_format (const ComplexMatrix& cm, int& r_fw, int& i_fw, double& scale)
1199 {
1200 curr_real_fmt = 0;
1201 curr_imag_fmt = 0;
1202
1203 if (free_format)
1204 return;
1205
1206 Matrix rp = real (cm);
1207 Matrix ip = imag (cm);
1208
1209 bool inf_or_nan = cm.any_element_is_inf_or_nan ();
1210
1211 bool int_or_inf_or_nan = (rp.all_elements_are_int_or_inf_or_nan ()
1212 && ip.all_elements_are_int_or_inf_or_nan ());
1213
1214 Matrix r_m_abs = rp.abs ();
1215 double r_max_abs = pr_max_internal (r_m_abs);
1216 double r_min_abs = pr_min_internal (r_m_abs);
1217
1218 Matrix i_m_abs = ip.abs ();
1219 double i_max_abs = pr_max_internal (i_m_abs);
1220 double i_min_abs = pr_min_internal (i_m_abs);
1221
1222 int r_x_max = r_max_abs == 0.0 ? 0 : num_digits (r_max_abs);
1223
1224 int r_x_min = r_min_abs == 0.0 ? 0 : num_digits (r_min_abs);
1225
1226 int i_x_max = i_max_abs == 0.0 ? 0 : num_digits (i_max_abs);
1227
1228 int i_x_min = i_min_abs == 0.0 ? 0 : num_digits (i_min_abs);
1229
1230 int x_max = r_x_max > i_x_max ? r_x_max : i_x_max;
1231 int x_min = r_x_min > i_x_min ? r_x_min : i_x_min;
1232
1233 scale = (x_max == 0 || int_or_inf_or_nan) ? 1.0
1234 : std::pow (10.0, calc_scale_exp (x_max - 1));
1235
1236 set_complex_matrix_format (x_max, x_min, r_x_max, r_x_min, inf_or_nan,
1237 int_or_inf_or_nan, r_fw, i_fw);
1238 }
1239
1240 static inline void
1241 set_format (const ComplexMatrix& cm)
1242 {
1243 int r_fw, i_fw;
1244 double scale;
1245 set_format (cm, r_fw, i_fw, scale);
1246 }
1247
1248 static void
1249 set_range_format (int x_max, int x_min, int all_ints, int& fw)
1250 {
1251 static float_format fmt;
1252
1253 int prec = Voutput_precision;
1254
1255 int ld, rd;
1256
1257 if (rat_format)
1258 {
1259 fw = 9;
1260 rd = 0;
1261 }
1262 else if (bank_format)
1263 {
1264 int digits = x_max > x_min ? x_max : x_min;
1265 fw = digits < 0 ? 5 : digits + 4;
1266 rd = 2;
1267 }
1268 else if (hex_format)
1269 {
1270 fw = 2 * sizeof (double);
1271 rd = 0;
1272 }
1273 else if (bit_format)
1274 {
1275 fw = 8 * sizeof (double);
1276 rd = 0;
1277 }
1278 else if (all_ints)
1279 {
1280 int digits = x_max > x_min ? x_max : x_min;
1281 fw = digits + 1;
1282 rd = fw;
1283 }
1284 else if (Vfixed_point_format && ! print_g)
1285 {
1286 rd = prec;
1287 fw = rd + 3;
1288 }
1289 else
1290 {
1291 int ld_max, rd_max;
1292 if (x_max > 0)
1293 {
1294 ld_max = x_max;
1295 rd_max = prec > x_max ? prec - x_max : prec;
1296 x_max++;
1297 }
1298 else
1299 {
1300 ld_max = 1;
1301 rd_max = prec > x_max ? prec - x_max : prec;
1302 x_max = -x_max + 1;
1303 }
1304
1305 int ld_min, rd_min;
1306 if (x_min > 0)
1307 {
1308 ld_min = x_min;
1309 rd_min = prec > x_min ? prec - x_min : prec;
1310 x_min++;
1311 }
1312 else
1313 {
1314 ld_min = 1;
1315 rd_min = prec > x_min ? prec - x_min : prec;
1316 x_min = -x_min + 1;
1317 }
1318
1319 ld = ld_max > ld_min ? ld_max : ld_min;
1320 rd = rd_max > rd_min ? rd_max : rd_min;
1321
1322 fw = ld + rd + 3;
1323 }
1324
1325 if (! (rat_format || bank_format || hex_format || bit_format)
1326 && (print_e
1327 || print_eng || print_g
1328 || (! Vfixed_point_format && fw > Voutput_max_field_width)))
1329 {
1330 if (print_g)
1331 fmt = float_format ();
1332 else
1333 {
1334 int ex = 4;
1335 if (x_max > 100 || x_min > 100)
1336 ex++;
1337
1338 if (print_eng)
1339 {
1340 fw = 5 + prec + ex;
1341 fmt = float_format (fw, ex, prec - 1, std::ios::fixed);
1342 }
1343 else
1344 {
1345 fw = 3 + prec + ex;
1346 fmt = float_format (fw, prec - 1, std::ios::scientific);
1347 }
1348 }
1349
1350 if (print_big_e)
1351 fmt.uppercase ();
1352 }
1353 else if (! bank_format && all_ints)
1354 fmt = float_format (fw, rd);
1355 else
1356 fmt = float_format (fw, rd, std::ios::fixed);
1357
1358 curr_real_fmt = &fmt;
1359 }
1360
1361 static void
1362 set_format (const Range& r, int& fw, double& scale)
1363 {
1364 curr_real_fmt = 0;
1365 curr_imag_fmt = 0;
1366
1367 if (free_format)
1368 return;
1369
1370 double r_min = r.base ();
1371 double r_max = r.limit ();
1372
1373 if (r_max < r_min)
1374 {
1375 double tmp = r_max;
1376 r_max = r_min;
1377 r_min = tmp;
1378 }
1379
1380 bool all_ints = r.all_elements_are_ints ();
1381
1382 double max_abs = r_max < 0.0 ? -r_max : r_max;
1383 double min_abs = r_min < 0.0 ? -r_min : r_min;
1384
1385 int x_max = max_abs == 0.0 ? 0 : num_digits (max_abs);
1386
1387 int x_min = min_abs == 0.0 ? 0 : num_digits (min_abs);
1388
1389 scale = (x_max == 0 || all_ints) ? 1.0
1390 : std::pow (10.0, calc_scale_exp (x_max - 1));
1391
1392 set_range_format (x_max, x_min, all_ints, fw);
1393 }
1394
1395 static inline void
1396 set_format (const Range& r)
1397 {
1398 int fw;
1399 double scale;
1400 set_format (r, fw, scale);
1401 }
1402
1403 union equiv
1404 {
1405 double d;
1406 unsigned char i[sizeof (double)];
1407 };
1408
1409 #define PRINT_CHAR_BITS(os, c) \
1410 do \
1411 { \
1412 unsigned char ctmp = c; \
1413 char stmp[9]; \
1414 stmp[0] = (ctmp & 0x80) ? '1' : '0'; \
1415 stmp[1] = (ctmp & 0x40) ? '1' : '0'; \
1416 stmp[2] = (ctmp & 0x20) ? '1' : '0'; \
1417 stmp[3] = (ctmp & 0x10) ? '1' : '0'; \
1418 stmp[4] = (ctmp & 0x08) ? '1' : '0'; \
1419 stmp[5] = (ctmp & 0x04) ? '1' : '0'; \
1420 stmp[6] = (ctmp & 0x02) ? '1' : '0'; \
1421 stmp[7] = (ctmp & 0x01) ? '1' : '0'; \
1422 stmp[8] = '\0'; \
1423 os << stmp; \
1424 } \
1425 while (0)
1426
1427 #define PRINT_CHAR_BITS_SWAPPED(os, c) \
1428 do \
1429 { \
1430 unsigned char ctmp = c; \
1431 char stmp[9]; \
1432 stmp[0] = (ctmp & 0x01) ? '1' : '0'; \
1433 stmp[1] = (ctmp & 0x02) ? '1' : '0'; \
1434 stmp[2] = (ctmp & 0x04) ? '1' : '0'; \
1435 stmp[3] = (ctmp & 0x08) ? '1' : '0'; \
1436 stmp[4] = (ctmp & 0x10) ? '1' : '0'; \
1437 stmp[5] = (ctmp & 0x20) ? '1' : '0'; \
1438 stmp[6] = (ctmp & 0x40) ? '1' : '0'; \
1439 stmp[7] = (ctmp & 0x80) ? '1' : '0'; \
1440 stmp[8] = '\0'; \
1441 os << stmp; \
1442 } \
1443 while (0)
1444
1445 static void
1446 pr_any_float (const float_format *fmt, std::ostream& os, double d, int fw = 0)
1447 {
1448 if (fmt)
1449 {
1450 // Unless explicitly asked for, always print in big-endian
1451 // format for hex and bit formats.
1452 //
1453 // {bit,hex}_format == 1: print big-endian
1454 // {bit,hex}_format == 2: print native
1455
1456 if (hex_format)
1457 {
1458 equiv tmp;
1459 tmp.d = d;
1460
1461 // Unless explicitly asked for, always print in big-endian
1462 // format.
1463
1464 // FIXME -- is it correct to swap bytes for VAX
1465 // formats and not for Cray?
1466
1467 // FIXME -- will bad things happen if we are
1468 // interrupted before resetting the format flags and fill
1469 // character?
1470
1471 oct_mach_info::float_format flt_fmt =
1472 oct_mach_info::native_float_format ();
1473
1474 char ofill = os.fill ('0');
1475
1476 std::ios::fmtflags oflags
1477 = os.flags (std::ios::right | std::ios::hex);
1478
1479 if (hex_format > 1
1480 || flt_fmt == oct_mach_info::flt_fmt_ieee_big_endian
1481 || flt_fmt == oct_mach_info::flt_fmt_cray
1482 || flt_fmt == oct_mach_info::flt_fmt_unknown)
1483 {
1484 for (size_t i = 0; i < sizeof (double); i++)
1485 os << std::setw (2) << static_cast<int> (tmp.i[i]);
1486 }
1487 else
1488 {
1489 for (int i = sizeof (double) - 1; i >= 0; i--)
1490 os << std::setw (2) << static_cast<int> (tmp.i[i]);
1491 }
1492
1493 os.fill (ofill);
1494 os.setf (oflags);
1495 }
1496 else if (bit_format)
1497 {
1498 equiv tmp;
1499 tmp.d = d;
1500
1501 // FIXME -- is it correct to swap bytes for VAX
1502 // formats and not for Cray?
1503
1504 oct_mach_info::float_format flt_fmt =
1505 oct_mach_info::native_float_format ();
1506
1507 if (flt_fmt == oct_mach_info::flt_fmt_ieee_big_endian
1508 || flt_fmt == oct_mach_info::flt_fmt_cray
1509 || flt_fmt == oct_mach_info::flt_fmt_unknown)
1510 {
1511 for (size_t i = 0; i < sizeof (double); i++)
1512 PRINT_CHAR_BITS (os, tmp.i[i]);
1513 }
1514 else
1515 {
1516 if (bit_format > 1)
1517 {
1518 for (size_t i = 0; i < sizeof (double); i++)
1519 PRINT_CHAR_BITS_SWAPPED (os, tmp.i[i]);
1520 }
1521 else
1522 {
1523 for (int i = sizeof (double) - 1; i >= 0; i--)
1524 PRINT_CHAR_BITS (os, tmp.i[i]);
1525 }
1526 }
1527 }
1528 else if (octave_is_NA (d))
1529 {
1530 if (fw > 0)
1531 os << std::setw (fw) << "NA";
1532 else
1533 os << "NA";
1534 }
1535 else if (rat_format)
1536 os << pr_rational_float (*fmt, d);
1537 else if (xisinf (d))
1538 {
1539 const char *s;
1540 if (d < 0.0)
1541 s = "-Inf";
1542 else
1543 s = "Inf";
1544
1545 if (fw > 0)
1546 os << std::setw (fw) << s;
1547 else
1548 os << s;
1549 }
1550 else if (xisnan (d))
1551 {
1552 if (fw > 0)
1553 os << std::setw (fw) << "NaN";
1554 else
1555 os << "NaN";
1556 }
1557 else if (print_eng)
1558 os << pr_engineering_float (*fmt, d);
1559 else
1560 os << pr_formatted_float (*fmt, d);
1561 }
1562 else
1563 os << d;
1564 }
1565
1566 static inline void
1567 pr_float (std::ostream& os, double d, int fw = 0, double scale = 1.0)
1568 {
1569 if (Vfixed_point_format && ! print_g && scale != 1.0)
1570 d /= scale;
1571
1572 pr_any_float (curr_real_fmt, os, d, fw);
1573 }
1574
1575 static inline void
1576 pr_imag_float (std::ostream& os, double d, int fw = 0)
1577 {
1578 pr_any_float (curr_imag_fmt, os, d, fw);
1579 }
1580
1581 static void
1582 pr_complex (std::ostream& os, const Complex& c, int r_fw = 0,
1583 int i_fw = 0, double scale = 1.0)
1584 {
1585 Complex tmp
1586 = (Vfixed_point_format && ! print_g && scale != 1.0) ? c / scale : c;
1587
1588 double r = tmp.real ();
1589
1590 pr_float (os, r, r_fw);
1591
1592 if (! bank_format)
1593 {
1594 double i = tmp.imag ();
1595 if (! (hex_format || bit_format) && lo_ieee_signbit (i))
1596 {
1597 os << " - ";
1598 i = -i;
1599 pr_imag_float (os, i, i_fw);
1600 }
1601 else
1602 {
1603 if (hex_format || bit_format)
1604 os << " ";
1605 else
1606 os << " + ";
1607
1608 pr_imag_float (os, i, i_fw);
1609 }
1610 os << "i";
1611 }
1612 }
1613
1614 static void
1615 print_empty_matrix (std::ostream& os, octave_idx_type nr, octave_idx_type nc, bool pr_as_read_syntax)
1616 {
1617 assert (nr == 0 || nc == 0);
1618
1619 if (pr_as_read_syntax)
1620 {
1621 if (nr == 0 && nc == 0)
1622 os << "[]";
1623 else
1624 os << "zeros (" << nr << ", " << nc << ")";
1625 }
1626 else
1627 {
1628 os << "[]";
1629
1630 if (Vprint_empty_dimensions)
1631 os << "(" << nr << "x" << nc << ")";
1632 }
1633 }
1634
1635 static void
1636 print_empty_nd_array (std::ostream& os, const dim_vector& dims,
1637 bool pr_as_read_syntax)
1638 {
1639 assert (dims.any_zero ());
1640
1641 if (pr_as_read_syntax)
1642 os << "zeros (" << dims.str (',') << ")";
1643 else
1644 {
1645 os << "[]";
1646
1647 if (Vprint_empty_dimensions)
1648 os << "(" << dims.str () << ")";
1649 }
1650 }
1651
1652 static void
1653 pr_scale_header (std::ostream& os, double scale)
1654 {
1655 if (Vfixed_point_format && ! print_g && scale != 1.0)
1656 {
1657 os << " "
1658 << std::setw (8) << std::setprecision (1)
1659 << std::setiosflags (std::ios::scientific|std::ios::left)
1660 << scale
1661 << std::resetiosflags (std::ios::scientific|std::ios::left)
1662 << " *\n";
1663
1664 if (! Vcompact_format)
1665 os << "\n";
1666 }
1667 }
1668
1669 static void
1670 pr_col_num_header (std::ostream& os, octave_idx_type total_width, int max_width,
1671 octave_idx_type lim, octave_idx_type col, int extra_indent)
1672 {
1673 if (total_width > max_width && Vsplit_long_rows)
1674 {
1675 if (col != 0)
1676 {
1677 if (Vcompact_format)
1678 os << "\n";
1679 else
1680 os << "\n\n";
1681 }
1682
1683 octave_idx_type num_cols = lim - col;
1684
1685 os << std::setw (extra_indent) << "";
1686
1687 if (num_cols == 1)
1688 os << " Column " << col + 1 << ":\n";
1689 else if (num_cols == 2)
1690 os << " Columns " << col + 1 << " and " << lim << ":\n";
1691 else
1692 os << " Columns " << col + 1 << " through " << lim << ":\n";
1693
1694 if (! Vcompact_format)
1695 os << "\n";
1696 }
1697 }
1698
1699 template <class T>
1700 /* static */ inline void
1701 pr_plus_format (std::ostream& os, const T& val)
1702 {
1703 if (val > T (0))
1704 os << plus_format_chars[0];
1705 else if (val < T (0))
1706 os << plus_format_chars[1];
1707 else
1708 os << plus_format_chars[2];
1709 }
1710
1711 void
1712 octave_print_internal (std::ostream& os, double d,
1713 bool /* pr_as_read_syntax */)
1714 {
1715 if (plus_format)
1716 {
1717 pr_plus_format (os, d);
1718 }
1719 else
1720 {
1721 set_format (d);
1722 if (free_format)
1723 os << d;
1724 else
1725 pr_float (os, d);
1726 }
1727 }
1728
1729 void
1730 octave_print_internal (std::ostream& os, const Matrix& m,
1731 bool pr_as_read_syntax, int extra_indent)
1732 {
1733 octave_idx_type nr = m.rows ();
1734 octave_idx_type nc = m.columns ();
1735
1736 if (nr == 0 || nc == 0)
1737 print_empty_matrix (os, nr, nc, pr_as_read_syntax);
1738 else if (plus_format && ! pr_as_read_syntax)
1739 {
1740 for (octave_idx_type i = 0; i < nr; i++)
1741 {
1742 for (octave_idx_type j = 0; j < nc; j++)
1743 {
1744 octave_quit ();
1745
1746 pr_plus_format (os, m(i,j));
1747 }
1748
1749 if (i < nr - 1)
1750 os << "\n";
1751 }
1752 }
1753 else
1754 {
1755 int fw;
1756 double scale = 1.0;
1757 set_format (m, fw, scale);
1758 int column_width = fw + 2;
1759 octave_idx_type total_width = nc * column_width;
1760 octave_idx_type max_width = command_editor::terminal_cols ();
1761
1762 if (pr_as_read_syntax)
1763 max_width -= 4;
1764 else
1765 max_width -= extra_indent;
1766
1767 if (max_width < 0)
1768 max_width = 0;
1769
1770 if (free_format)
1771 {
1772 if (pr_as_read_syntax)
1773 os << "[\n";
1774
1775 os << m;
1776
1777 if (pr_as_read_syntax)
1778 os << "]";
1779
1780 return;
1781 }
1782
1783 octave_idx_type inc = nc;
1784 if (total_width > max_width && Vsplit_long_rows)
1785 {
1786 inc = max_width / column_width;
1787 if (inc == 0)
1788 inc++;
1789 }
1790
1791 if (pr_as_read_syntax)
1792 {
1793 for (octave_idx_type i = 0; i < nr; i++)
1794 {
1795 octave_idx_type col = 0;
1796 while (col < nc)
1797 {
1798 octave_idx_type lim = col + inc < nc ? col + inc : nc;
1799
1800 for (octave_idx_type j = col; j < lim; j++)
1801 {
1802 octave_quit ();
1803
1804 if (i == 0 && j == 0)
1805 os << "[ ";
1806 else
1807 {
1808 if (j > col && j < lim)
1809 os << ", ";
1810 else
1811 os << " ";
1812 }
1813
1814 pr_float (os, m(i,j));
1815 }
1816
1817 col += inc;
1818
1819 if (col >= nc)
1820 {
1821 if (i == nr - 1)
1822 os << " ]";
1823 else
1824 os << ";\n";
1825 }
1826 else
1827 os << " ...\n";
1828 }
1829 }
1830 }
1831 else
1832 {
1833 pr_scale_header (os, scale);
1834
1835 for (octave_idx_type col = 0; col < nc; col += inc)
1836 {
1837 octave_idx_type lim = col + inc < nc ? col + inc : nc;
1838
1839 pr_col_num_header (os, total_width, max_width, lim, col,
1840 extra_indent);
1841
1842 for (octave_idx_type i = 0; i < nr; i++)
1843 {
1844 os << std::setw (extra_indent) << "";
1845
1846 for (octave_idx_type j = col; j < lim; j++)
1847 {
1848 octave_quit ();
1849
1850 os << " ";
1851
1852 pr_float (os, m(i,j), fw, scale);
1853 }
1854
1855 if (i < nr - 1)
1856 os << "\n";
1857 }
1858 }
1859 }
1860 }
1861 }
1862
1863 void
1864 octave_print_internal (std::ostream& os, const DiagMatrix& m,
1865 bool pr_as_read_syntax, int extra_indent)
1866 {
1867 octave_idx_type nr = m.rows ();
1868 octave_idx_type nc = m.columns ();
1869
1870 if (nr == 0 || nc == 0)
1871 print_empty_matrix (os, nr, nc, pr_as_read_syntax);
1872 else if (plus_format && ! pr_as_read_syntax)
1873 {
1874 for (octave_idx_type i = 0; i < nr; i++)
1875 {
1876 for (octave_idx_type j = 0; j < nc; j++)
1877 {
1878 octave_quit ();
1879
1880 pr_plus_format (os, m(i,j));
1881 }
1882
1883 if (i < nr - 1)
1884 os << "\n";
1885 }
1886 }
1887 else
1888 {
1889 int fw;
1890 double scale = 1.0;
1891 set_format (Matrix (m.diag ()), fw, scale);
1892 int column_width = fw + 2;
1893 octave_idx_type total_width = nc * column_width;
1894 octave_idx_type max_width = command_editor::terminal_cols ();
1895
1896 if (pr_as_read_syntax)
1897 max_width -= 4;
1898 else
1899 max_width -= extra_indent;
1900
1901 if (max_width < 0)
1902 max_width = 0;
1903
1904 if (free_format)
1905 {
1906 if (pr_as_read_syntax)
1907 os << "[\n";
1908
1909 os << Matrix (m);
1910
1911 if (pr_as_read_syntax)
1912 os << "]";
1913
1914 return;
1915 }
1916
1917 octave_idx_type inc = nc;
1918 if (total_width > max_width && Vsplit_long_rows)
1919 {
1920 inc = max_width / column_width;
1921 if (inc == 0)
1922 inc++;
1923 }
1924
1925 if (pr_as_read_syntax)
1926 {
1927 os << "diag (";
1928
1929 octave_idx_type col = 0;
1930 while (col < nc)
1931 {
1932 octave_idx_type lim = col + inc < nc ? col + inc : nc;
1933
1934 for (octave_idx_type j = col; j < lim; j++)
1935 {
1936 octave_quit ();
1937
1938 if (j == 0)
1939 os << "[ ";
1940 else
1941 {
1942 if (j > col && j < lim)
1943 os << ", ";
1944 else
1945 os << " ";
1946 }
1947
1948 pr_float (os, m(j,j));
1949 }
1950
1951 col += inc;
1952
1953 if (col >= nc)
1954 os << " ]";
1955 else
1956 os << " ...\n";
1957 }
1958 os << ")";
1959 }
1960 else
1961 {
1962 os << "Diagonal Matrix\n";
1963 if (! Vcompact_format)
1964 os << "\n";
1965
1966 pr_scale_header (os, scale);
1967
1968 // kluge. Get the true width of a number.
1969 int zero_fw;
1970
1971 {
1972 std::ostringstream tmp_oss;
1973 pr_float (tmp_oss, 0.0, fw, scale);
1974 zero_fw = tmp_oss.str ().length ();
1975 }
1976
1977 for (octave_idx_type col = 0; col < nc; col += inc)
1978 {
1979 octave_idx_type lim = col + inc < nc ? col + inc : nc;
1980
1981 pr_col_num_header (os, total_width, max_width, lim, col,
1982 extra_indent);
1983
1984 for (octave_idx_type i = 0; i < nr; i++)
1985 {
1986 os << std::setw (extra_indent) << "";
1987
1988 for (octave_idx_type j = col; j < lim; j++)
1989 {
1990 octave_quit ();
1991
1992 os << " ";
1993
1994 if (i == j)
1995 pr_float (os, m(i,j), fw, scale);
1996 else
1997 os << std::setw (zero_fw) << '0';
1998
1999 }
2000
2001 if (i < nr - 1)
2002 os << "\n";
2003 }
2004 }
2005 }
2006 }
2007 }
2008
2009 template <typename NDA_T, typename ELT_T, typename MAT_T>
2010 void print_nd_array (std::ostream& os, const NDA_T& nda,
2011 bool pr_as_read_syntax)
2012 {
2013
2014 if (nda.is_empty ())
2015 print_empty_nd_array (os, nda.dims (), pr_as_read_syntax);
2016 else
2017 {
2018
2019 int ndims = nda.ndims ();
2020
2021 dim_vector dims = nda.dims ();
2022
2023 Array<octave_idx_type> ra_idx (dim_vector (ndims, 1), 0);
2024
2025 octave_idx_type m = 1;
2026
2027 for (int i = 2; i < ndims; i++)
2028 m *= dims(i);
2029
2030 octave_idx_type nr = dims(0);
2031 octave_idx_type nc = dims(1);
2032
2033 for (octave_idx_type i = 0; i < m; i++)
2034 {
2035 octave_quit ();
2036
2037 std::string nm = "ans";
2038
2039 if (m > 1)
2040 {
2041 nm += "(:,:,";
2042
2043 std::ostringstream buf;
2044
2045 for (int k = 2; k < ndims; k++)
2046 {
2047 buf << ra_idx(k) + 1;
2048
2049 if (k < ndims - 1)
2050 buf << ",";
2051 else
2052 buf << ")";
2053 }
2054
2055 nm += buf.str ();
2056 }
2057
2058 Array<idx_vector> idx (dim_vector (ndims, 1));
2059
2060 idx(0) = idx_vector (':');
2061 idx(1) = idx_vector (':');
2062
2063 for (int k = 2; k < ndims; k++)
2064 idx(k) = idx_vector (ra_idx(k));
2065
2066 octave_value page
2067 = MAT_T (Array<ELT_T> (nda.index (idx), dim_vector (nr, nc)));
2068
2069 if (i != m - 1)
2070 {
2071 page.print_with_name (os, nm);
2072 }
2073 else
2074 {
2075 page.print_name_tag (os, nm);
2076 page.print_raw (os);
2077 }
2078
2079 if (i < m)
2080 NDA_T::increment_index (ra_idx, dims, 2);
2081 }
2082 }
2083 }
2084
2085 void
2086 octave_print_internal (std::ostream& os, const NDArray& nda,
2087 bool pr_as_read_syntax, int extra_indent)
2088 {
2089 switch (nda.ndims ())
2090 {
2091 case 1:
2092 case 2:
2093 octave_print_internal (os, nda.matrix_value (),
2094 pr_as_read_syntax, extra_indent);
2095 break;
2096
2097 default:
2098 print_nd_array <NDArray, double, Matrix> (os, nda, pr_as_read_syntax);
2099 break;
2100 }
2101 }
2102
2103 template <>
2104 /* static */ inline void
2105 pr_plus_format<> (std::ostream& os, const Complex& c)
2106 {
2107 double rp = c.real ();
2108 double ip = c.imag ();
2109
2110 if (rp == 0.0)
2111 {
2112 if (ip == 0.0)
2113 os << " ";
2114 else
2115 os << "i";
2116 }
2117 else if (ip == 0.0)
2118 pr_plus_format (os, rp);
2119 else
2120 os << "c";
2121 }
2122
2123 void
2124 octave_print_internal (std::ostream& os, const Complex& c,
2125 bool /* pr_as_read_syntax */)
2126 {
2127 if (plus_format)
2128 {
2129 pr_plus_format (os, c);
2130 }
2131 else
2132 {
2133 set_format (c);
2134 if (free_format)
2135 os << c;
2136 else
2137 pr_complex (os, c);
2138 }
2139 }
2140
2141 void
2142 octave_print_internal (std::ostream& os, const ComplexMatrix& cm,
2143 bool pr_as_read_syntax, int extra_indent)
2144 {
2145 octave_idx_type nr = cm.rows ();
2146 octave_idx_type nc = cm.columns ();
2147
2148 if (nr == 0 || nc == 0)
2149 print_empty_matrix (os, nr, nc, pr_as_read_syntax);
2150 else if (plus_format && ! pr_as_read_syntax)
2151 {
2152 for (octave_idx_type i = 0; i < nr; i++)
2153 {
2154 for (octave_idx_type j = 0; j < nc; j++)
2155 {
2156 octave_quit ();
2157
2158 pr_plus_format (os, cm(i,j));
2159 }
2160
2161 if (i < nr - 1)
2162 os << "\n";
2163 }
2164 }
2165 else
2166 {
2167 int r_fw, i_fw;
2168 double scale = 1.0;
2169 set_format (cm, r_fw, i_fw, scale);
2170 int column_width = i_fw + r_fw;
2171 column_width += (rat_format || bank_format || hex_format
2172 || bit_format) ? 2 : 7;
2173 octave_idx_type total_width = nc * column_width;
2174 octave_idx_type max_width = command_editor::terminal_cols ();
2175
2176 if (pr_as_read_syntax)
2177 max_width -= 4;
2178 else
2179 max_width -= extra_indent;
2180
2181 if (max_width < 0)
2182 max_width = 0;
2183
2184 if (free_format)
2185 {
2186 if (pr_as_read_syntax)
2187 os << "[\n";
2188
2189 os << cm;
2190
2191 if (pr_as_read_syntax)
2192 os << "]";
2193
2194 return;
2195 }
2196
2197 octave_idx_type inc = nc;
2198 if (total_width > max_width && Vsplit_long_rows)
2199 {
2200 inc = max_width / column_width;
2201 if (inc == 0)
2202 inc++;
2203 }
2204
2205 if (pr_as_read_syntax)
2206 {
2207 for (octave_idx_type i = 0; i < nr; i++)
2208 {
2209 octave_idx_type col = 0;
2210 while (col < nc)
2211 {
2212 octave_idx_type lim = col + inc < nc ? col + inc : nc;
2213
2214 for (octave_idx_type j = col; j < lim; j++)
2215 {
2216 octave_quit ();
2217
2218 if (i == 0 && j == 0)
2219 os << "[ ";
2220 else
2221 {
2222 if (j > col && j < lim)
2223 os << ", ";
2224 else
2225 os << " ";
2226 }
2227
2228 pr_complex (os, cm(i,j));
2229 }
2230
2231 col += inc;
2232
2233 if (col >= nc)
2234 {
2235 if (i == nr - 1)
2236 os << " ]";
2237 else
2238 os << ";\n";
2239 }
2240 else
2241 os << " ...\n";
2242 }
2243 }
2244 }
2245 else
2246 {
2247 pr_scale_header (os, scale);
2248
2249 for (octave_idx_type col = 0; col < nc; col += inc)
2250 {
2251 octave_idx_type lim = col + inc < nc ? col + inc : nc;
2252
2253 pr_col_num_header (os, total_width, max_width, lim, col,
2254 extra_indent);
2255
2256 for (octave_idx_type i = 0; i < nr; i++)
2257 {
2258 os << std::setw (extra_indent) << "";
2259
2260 for (octave_idx_type j = col; j < lim; j++)
2261 {
2262 octave_quit ();
2263
2264 os << " ";
2265
2266 pr_complex (os, cm(i,j), r_fw, i_fw, scale);
2267 }
2268
2269 if (i < nr - 1)
2270 os << "\n";
2271 }
2272 }
2273 }
2274 }
2275 }
2276
2277 void
2278 octave_print_internal (std::ostream& os, const ComplexDiagMatrix& cm,
2279 bool pr_as_read_syntax, int extra_indent)
2280 {
2281 octave_idx_type nr = cm.rows ();
2282 octave_idx_type nc = cm.columns ();
2283
2284 if (nr == 0 || nc == 0)
2285 print_empty_matrix (os, nr, nc, pr_as_read_syntax);
2286 else if (plus_format && ! pr_as_read_syntax)
2287 {
2288 for (octave_idx_type i = 0; i < nr; i++)
2289 {
2290 for (octave_idx_type j = 0; j < nc; j++)
2291 {
2292 octave_quit ();
2293
2294 pr_plus_format (os, cm(i,j));
2295 }
2296
2297 if (i < nr - 1)
2298 os << "\n";
2299 }
2300 }
2301 else
2302 {
2303 int r_fw, i_fw;
2304 double scale = 1.0;
2305 set_format (ComplexMatrix (cm.diag ()), r_fw, i_fw, scale);
2306 int column_width = i_fw + r_fw;
2307 column_width += (rat_format || bank_format || hex_format
2308 || bit_format) ? 2 : 7;
2309 octave_idx_type total_width = nc * column_width;
2310 octave_idx_type max_width = command_editor::terminal_cols ();
2311
2312 if (pr_as_read_syntax)
2313 max_width -= 4;
2314 else
2315 max_width -= extra_indent;
2316
2317 if (max_width < 0)
2318 max_width = 0;
2319
2320 if (free_format)
2321 {
2322 if (pr_as_read_syntax)
2323 os << "[\n";
2324
2325 os << ComplexMatrix (cm);
2326
2327 if (pr_as_read_syntax)
2328 os << "]";
2329
2330 return;
2331 }
2332
2333 octave_idx_type inc = nc;
2334 if (total_width > max_width && Vsplit_long_rows)
2335 {
2336 inc = max_width / column_width;
2337 if (inc == 0)
2338 inc++;
2339 }
2340
2341 if (pr_as_read_syntax)
2342 {
2343 os << "diag (";
2344
2345 octave_idx_type col = 0;
2346 while (col < nc)
2347 {
2348 octave_idx_type lim = col + inc < nc ? col + inc : nc;
2349
2350 for (octave_idx_type j = col; j < lim; j++)
2351 {
2352 octave_quit ();
2353
2354 if (j == 0)
2355 os << "[ ";
2356 else
2357 {
2358 if (j > col && j < lim)
2359 os << ", ";
2360 else
2361 os << " ";
2362 }
2363
2364 pr_complex (os, cm(j,j));
2365 }
2366
2367 col += inc;
2368
2369 if (col >= nc)
2370 os << " ]";
2371 else
2372 os << " ...\n";
2373 }
2374 os << ")";
2375 }
2376 else
2377 {
2378 os << "Diagonal Matrix\n";
2379 if (! Vcompact_format)
2380 os << "\n";
2381
2382 pr_scale_header (os, scale);
2383
2384 // kluge. Get the true width of a number.
2385 int zero_fw;
2386
2387 {
2388 std::ostringstream tmp_oss;
2389 pr_complex (tmp_oss, Complex (0.0), r_fw, i_fw, scale);
2390 zero_fw = tmp_oss.str ().length ();
2391 }
2392
2393 for (octave_idx_type col = 0; col < nc; col += inc)
2394 {
2395 octave_idx_type lim = col + inc < nc ? col + inc : nc;
2396
2397 pr_col_num_header (os, total_width, max_width, lim, col,
2398 extra_indent);
2399
2400 for (octave_idx_type i = 0; i < nr; i++)
2401 {
2402 os << std::setw (extra_indent) << "";
2403
2404 for (octave_idx_type j = col; j < lim; j++)
2405 {
2406 octave_quit ();
2407
2408 os << " ";
2409
2410 if (i == j)
2411 pr_complex (os, cm(i,j), r_fw, i_fw, scale);
2412 else
2413 os << std::setw (zero_fw) << '0';
2414 }
2415
2416 if (i < nr - 1)
2417 os << "\n";
2418 }
2419 }
2420 }
2421 }
2422 }
2423
2424 void
2425 octave_print_internal (std::ostream& os, const PermMatrix& m,
2426 bool pr_as_read_syntax, int extra_indent)
2427 {
2428 octave_idx_type nr = m.rows ();
2429 octave_idx_type nc = m.columns ();
2430
2431 if (nr == 0 || nc == 0)
2432 print_empty_matrix (os, nr, nc, pr_as_read_syntax);
2433 else if (plus_format && ! pr_as_read_syntax)
2434 {
2435 for (octave_idx_type i = 0; i < nr; i++)
2436 {
2437 for (octave_idx_type j = 0; j < nc; j++)
2438 {
2439 octave_quit ();
2440
2441 pr_plus_format (os, m(i,j));
2442 }
2443
2444 if (i < nr - 1)
2445 os << "\n";
2446 }
2447 }
2448 else
2449 {
2450 int fw = 2;
2451 int column_width = fw + 2;
2452 octave_idx_type total_width = nc * column_width;
2453 octave_idx_type max_width = command_editor::terminal_cols ();
2454
2455 if (pr_as_read_syntax)
2456 max_width -= 4;
2457 else
2458 max_width -= extra_indent;
2459
2460 if (max_width < 0)
2461 max_width = 0;
2462
2463 if (free_format)
2464 {
2465 if (pr_as_read_syntax)
2466 os << "[\n";
2467
2468 os << Matrix (m);
2469
2470 if (pr_as_read_syntax)
2471 os << "]";
2472
2473 return;
2474 }
2475
2476 octave_idx_type inc = nc;
2477 if (total_width > max_width && Vsplit_long_rows)
2478 {
2479 inc = max_width / column_width;
2480 if (inc == 0)
2481 inc++;
2482 }
2483
2484 if (pr_as_read_syntax)
2485 {
2486 Array<octave_idx_type> pvec = m.pvec ();
2487 bool colp = m.is_col_perm ();
2488
2489 os << "eye (";
2490 if (colp) os << ":, ";
2491
2492 octave_idx_type col = 0;
2493 while (col < nc)
2494 {
2495 octave_idx_type lim = col + inc < nc ? col + inc : nc;
2496
2497 for (octave_idx_type j = col; j < lim; j++)
2498 {
2499 octave_quit ();
2500
2501 if (j == 0)
2502 os << "[ ";
2503 else
2504 {
2505 if (j > col && j < lim)
2506 os << ", ";
2507 else
2508 os << " ";
2509 }
2510
2511 os << pvec (j);
2512 }
2513
2514 col += inc;
2515
2516 if (col >= nc)
2517 os << " ]";
2518 else
2519 os << " ...\n";
2520 }
2521 if (! colp) os << ", :";
2522 os << ")";
2523 }
2524 else
2525 {
2526 os << "Permutation Matrix\n";
2527 if (! Vcompact_format)
2528 os << "\n";
2529
2530 for (octave_idx_type col = 0; col < nc; col += inc)
2531 {
2532 octave_idx_type lim = col + inc < nc ? col + inc : nc;
2533
2534 pr_col_num_header (os, total_width, max_width, lim, col,
2535 extra_indent);
2536
2537 for (octave_idx_type i = 0; i < nr; i++)
2538 {
2539 os << std::setw (extra_indent) << "";
2540
2541 for (octave_idx_type j = col; j < lim; j++)
2542 {
2543 octave_quit ();
2544
2545 os << " ";
2546
2547 os << std::setw (fw) << m(i,j);
2548 }
2549
2550 if (i < nr - 1)
2551 os << "\n";
2552 }
2553 }
2554 }
2555 }
2556 }
2557
2558 void
2559 octave_print_internal (std::ostream& os, const ComplexNDArray& nda,
2560 bool pr_as_read_syntax, int extra_indent)
2561 {
2562 switch (nda.ndims ())
2563 {
2564 case 1:
2565 case 2:
2566 octave_print_internal (os, nda.matrix_value (),
2567 pr_as_read_syntax, extra_indent);
2568 break;
2569
2570 default:
2571 print_nd_array <ComplexNDArray, Complex,
2572 ComplexMatrix> (os, nda, pr_as_read_syntax);
2573 break;
2574 }
2575 }
2576
2577 void
2578 octave_print_internal (std::ostream& os, bool d, bool pr_as_read_syntax)
2579 {
2580 octave_print_internal (os, double (d), pr_as_read_syntax);
2581 }
2582
2583 // FIXME -- write single precision versions of the printing functions.
2584
2585 void
2586 octave_print_internal (std::ostream& os, float d, bool pr_as_read_syntax)
2587 {
2588 octave_print_internal (os, double (d), pr_as_read_syntax);
2589 }
2590
2591 void
2592 octave_print_internal (std::ostream& os, const FloatMatrix& m,
2593 bool pr_as_read_syntax, int extra_indent)
2594 {
2595 octave_print_internal (os, Matrix (m), pr_as_read_syntax, extra_indent);
2596 }
2597
2598 void
2599 octave_print_internal (std::ostream& os, const FloatDiagMatrix& m,
2600 bool pr_as_read_syntax, int extra_indent)
2601 {
2602 octave_print_internal (os, DiagMatrix (m), pr_as_read_syntax, extra_indent);
2603 }
2604
2605 void
2606 octave_print_internal (std::ostream& os, const FloatNDArray& nda,
2607 bool pr_as_read_syntax, int extra_indent)
2608 {
2609 octave_print_internal (os, NDArray (nda), pr_as_read_syntax, extra_indent);
2610 }
2611
2612 void
2613 octave_print_internal (std::ostream& os, const FloatComplex& c,
2614 bool pr_as_read_syntax)
2615 {
2616 octave_print_internal (os, Complex (c), pr_as_read_syntax);
2617 }
2618
2619 void
2620 octave_print_internal (std::ostream& os, const FloatComplexMatrix& cm,
2621 bool pr_as_read_syntax, int extra_indent)
2622 {
2623 octave_print_internal (os, ComplexMatrix (cm), pr_as_read_syntax, extra_indent);
2624 }
2625
2626 void
2627 octave_print_internal (std::ostream& os, const FloatComplexDiagMatrix& cm,
2628 bool pr_as_read_syntax, int extra_indent)
2629 {
2630 octave_print_internal (os, ComplexDiagMatrix (cm), pr_as_read_syntax, extra_indent);
2631 }
2632
2633 void
2634 octave_print_internal (std::ostream& os, const FloatComplexNDArray& nda,
2635 bool pr_as_read_syntax, int extra_indent)
2636 {
2637 octave_print_internal (os, ComplexNDArray (nda), pr_as_read_syntax, extra_indent);
2638 }
2639
2640 void
2641 octave_print_internal (std::ostream& os, const Range& r,
2642 bool pr_as_read_syntax, int extra_indent)
2643 {
2644 double base = r.base ();
2645 double increment = r.inc ();
2646 double limit = r.limit ();
2647 octave_idx_type num_elem = r.nelem ();
2648
2649 if (plus_format && ! pr_as_read_syntax)
2650 {
2651 for (octave_idx_type i = 0; i < num_elem; i++)
2652 {
2653 octave_quit ();
2654
2655 double val = base + i * increment;
2656
2657 pr_plus_format (os, val);
2658 }
2659 }
2660 else
2661 {
2662 int fw = 0;
2663 double scale = 1.0;
2664 set_format (r, fw, scale);
2665
2666 if (pr_as_read_syntax)
2667 {
2668 if (free_format)
2669 {
2670 os << base << " : ";
2671 if (increment != 1.0)
2672 os << increment << " : ";
2673 os << limit;
2674 }
2675 else
2676 {
2677 pr_float (os, base, fw);
2678 os << " : ";
2679 if (increment != 1.0)
2680 {
2681 pr_float (os, increment, fw);
2682 os << " : ";
2683 }
2684 pr_float (os, limit, fw);
2685 }
2686 }
2687 else
2688 {
2689 int column_width = fw + 2;
2690 octave_idx_type total_width = num_elem * column_width;
2691 octave_idx_type max_width = command_editor::terminal_cols ();
2692
2693 if (free_format)
2694 {
2695 os << r;
2696 return;
2697 }
2698
2699 octave_idx_type inc = num_elem;
2700 if (total_width > max_width && Vsplit_long_rows)
2701 {
2702 inc = max_width / column_width;
2703 if (inc == 0)
2704 inc++;
2705 }
2706
2707 max_width -= extra_indent;
2708
2709 if (max_width < 0)
2710 max_width = 0;
2711
2712 pr_scale_header (os, scale);
2713
2714 octave_idx_type col = 0;
2715 while (col < num_elem)
2716 {
2717 octave_idx_type lim = col + inc < num_elem ? col + inc : num_elem;
2718
2719 pr_col_num_header (os, total_width, max_width, lim, col,
2720 extra_indent);
2721
2722 os << std::setw (extra_indent) << "";
2723
2724 for (octave_idx_type i = col; i < lim; i++)
2725 {
2726 octave_quit ();
2727
2728 double val;
2729 if (i == 0)
2730 val = base;
2731 else
2732 val = base + i * increment;
2733
2734 if (i == num_elem - 1)
2735 {
2736 // See the comments in Range::matrix_value.
2737 if ((increment > 0 && val >= limit)
2738 || (increment < 0 && val <= limit))
2739 val = limit;
2740 }
2741
2742 os << " ";
2743
2744 pr_float (os, val, fw, scale);
2745 }
2746
2747 col += inc;
2748 }
2749 }
2750 }
2751 }
2752
2753 void
2754 octave_print_internal (std::ostream& os, const boolMatrix& bm,
2755 bool pr_as_read_syntax,
2756 int extra_indent)
2757 {
2758 Matrix tmp (bm);
2759 octave_print_internal (os, tmp, pr_as_read_syntax, extra_indent);
2760 }
2761
2762 void
2763 octave_print_internal (std::ostream& os, const boolNDArray& nda,
2764 bool pr_as_read_syntax,
2765 int extra_indent)
2766 {
2767 switch (nda.ndims ())
2768 {
2769 case 1:
2770 case 2:
2771 octave_print_internal (os, nda.matrix_value (),
2772 pr_as_read_syntax, extra_indent);
2773 break;
2774
2775 default:
2776 print_nd_array<boolNDArray, bool,
2777 boolMatrix> (os, nda, pr_as_read_syntax);
2778 break;
2779 }
2780 }
2781
2782 void
2783 octave_print_internal (std::ostream& os, const charMatrix& chm,
2784 bool pr_as_read_syntax,
2785 int /* extra_indent FIXME */,
2786 bool pr_as_string)
2787 {
2788 if (pr_as_string)
2789 {
2790 octave_idx_type nstr = chm.rows ();
2791
2792 if (pr_as_read_syntax && nstr > 1)
2793 os << "[ ";
2794
2795 if (nstr != 0)
2796 {
2797 for (octave_idx_type i = 0; i < nstr; i++)
2798 {
2799 octave_quit ();
2800
2801 std::string row = chm.row_as_string (i);
2802
2803 if (pr_as_read_syntax)
2804 {
2805 os << "\"" << undo_string_escapes (row) << "\"";
2806
2807 if (i < nstr - 1)
2808 os << "; ";
2809 }
2810 else
2811 {
2812 os << row;
2813
2814 if (i < nstr - 1)
2815 os << "\n";
2816 }
2817 }
2818 }
2819
2820 if (pr_as_read_syntax && nstr > 1)
2821 os << " ]";
2822 }
2823 else
2824 {
2825 os << "sorry, printing char matrices not implemented yet\n";
2826 }
2827 }
2828
2829 void
2830 octave_print_internal (std::ostream& os, const charNDArray& nda,
2831 bool pr_as_read_syntax, int extra_indent,
2832 bool pr_as_string)
2833 {
2834 switch (nda.ndims ())
2835 {
2836 case 1:
2837 case 2:
2838 octave_print_internal (os, nda.matrix_value (),
2839 pr_as_read_syntax, extra_indent, pr_as_string);
2840 break;
2841
2842 default:
2843 print_nd_array <charNDArray, char,
2844 charMatrix> (os, nda, pr_as_read_syntax);
2845 break;
2846 }
2847 }
2848
2849 void
2850 octave_print_internal (std::ostream& os, const std::string& s,
2851 bool pr_as_read_syntax, int extra_indent)
2852 {
2853 Array<std::string> nda (dim_vector (1, 1), s);
2854
2855 octave_print_internal (os, nda, pr_as_read_syntax, extra_indent);
2856 }
2857
2858 void
2859 octave_print_internal (std::ostream& os, const Array<std::string>& nda,
2860 bool pr_as_read_syntax, int /* extra_indent */)
2861 {
2862 // FIXME -- this mostly duplicates the code in the print_nd_array<>
2863 // function. Can fix this with std::is_same from C++11.
2864
2865 if (nda.is_empty ())
2866 print_empty_nd_array (os, nda.dims (), pr_as_read_syntax);
2867 else if (nda.length () == 1)
2868 {
2869 os << nda(0);
2870 }
2871 else
2872 {
2873 int ndims = nda.ndims ();
2874
2875 dim_vector dims = nda.dims ();
2876
2877 Array<octave_idx_type> ra_idx (dim_vector (ndims, 1), 0);
2878
2879 octave_idx_type m = 1;
2880
2881 for (int i = 2; i < ndims; i++)
2882 m *= dims(i);
2883
2884 octave_idx_type nr = dims(0);
2885 octave_idx_type nc = dims(1);
2886
2887 for (octave_idx_type i = 0; i < m; i++)
2888 {
2889 std::string nm = "ans";
2890
2891 if (m > 1)
2892 {
2893 nm += "(:,:,";
2894
2895 std::ostringstream buf;
2896
2897 for (int k = 2; k < ndims; k++)
2898 {
2899 buf << ra_idx(k) + 1;
2900
2901 if (k < ndims - 1)
2902 buf << ",";
2903 else
2904 buf << ")";
2905 }
2906
2907 nm += buf.str ();
2908 }
2909
2910 Array<idx_vector> idx (dim_vector (ndims, 1));
2911
2912 idx(0) = idx_vector (':');
2913 idx(1) = idx_vector (':');
2914
2915 for (int k = 2; k < ndims; k++)
2916 idx(k) = idx_vector (ra_idx(k));
2917
2918 Array<std::string> page (nda.index (idx), dim_vector (nr, nc));
2919
2920 // FIXME -- need to do some more work to put these
2921 // in neatly aligned columns...
2922
2923 octave_idx_type n_rows = page.rows ();
2924 octave_idx_type n_cols = page.cols ();
2925
2926 os << nm << " =\n";
2927 if (! Vcompact_format)
2928 os << "\n";
2929
2930 for (octave_idx_type ii = 0; ii < n_rows; ii++)
2931 {
2932 for (octave_idx_type jj = 0; jj < n_cols; jj++)
2933 os << " " << page(ii,jj);
2934
2935 os << "\n";
2936 }
2937
2938 if (i < m - 1)
2939 os << "\n";
2940
2941 if (i < m)
2942 increment_index (ra_idx, dims, 2);
2943 }
2944 }
2945 }
2946
2947 template <class T>
2948 class
2949 octave_print_conv
2950 {
2951 public:
2952 typedef T print_conv_type;
2953 };
2954
2955 #define PRINT_CONV(T1, T2) \
2956 template <> \
2957 class \
2958 octave_print_conv<T1> \
2959 { \
2960 public: \
2961 typedef T2 print_conv_type; \
2962 }
2963
2964 PRINT_CONV (octave_int8, octave_int16);
2965 PRINT_CONV (octave_uint8, octave_uint16);
2966
2967 #undef PRINT_CONV
2968
2969 template <class T>
2970 /* static */ inline void
2971 pr_int (std::ostream& os, const T& d, int fw = 0)
2972 {
2973 size_t sz = d.byte_size ();
2974 const unsigned char * tmpi = d.iptr ();
2975
2976 // Unless explicitly asked for, always print in big-endian
2977 // format for hex and bit formats.
2978 //
2979 // {bit,hex}_format == 1: print big-endian
2980 // {bit,hex}_format == 2: print native
2981
2982 if (hex_format)
2983 {
2984 char ofill = os.fill ('0');
2985
2986 std::ios::fmtflags oflags
2987 = os.flags (std::ios::right | std::ios::hex);
2988
2989 if (hex_format > 1 || oct_mach_info::words_big_endian ())
2990 {
2991 for (size_t i = 0; i < sz; i++)
2992 os << std::setw (2) << static_cast<int> (tmpi[i]);
2993 }
2994 else
2995 {
2996 for (int i = sz - 1; i >= 0; i--)
2997 os << std::setw (2) << static_cast<int> (tmpi[i]);
2998 }
2999
3000 os.fill (ofill);
3001 os.setf (oflags);
3002 }
3003 else if (bit_format)
3004 {
3005 if (oct_mach_info::words_big_endian ())
3006 {
3007 for (size_t i = 0; i < sz; i++)
3008 PRINT_CHAR_BITS (os, tmpi[i]);
3009 }
3010 else
3011 {
3012 if (bit_format > 1)
3013 {
3014 for (size_t i = 0; i < sz; i++)
3015 PRINT_CHAR_BITS_SWAPPED (os, tmpi[i]);
3016 }
3017 else
3018 {
3019 for (int i = sz - 1; i >= 0; i--)
3020 PRINT_CHAR_BITS (os, tmpi[i]);
3021 }
3022 }
3023 }
3024 else
3025 {
3026 os << std::setw (fw)
3027 << typename octave_print_conv<T>::print_conv_type (d);
3028
3029 if (bank_format)
3030 os << ".00";
3031 }
3032 }
3033
3034 // FIXME -- all this mess with abs is an attempt to avoid seeing
3035 //
3036 // warning: comparison of unsigned expression < 0 is always false
3037 //
3038 // from GCC. Isn't there a better way
3039
3040 template <class T>
3041 /* static */ inline T
3042 abs (T x)
3043 {
3044 return x < 0 ? -x : x;
3045 }
3046
3047 #define INSTANTIATE_ABS(T) \
3048 template /* static */ T abs (T)
3049
3050 INSTANTIATE_ABS(signed char);
3051 INSTANTIATE_ABS(short);
3052 INSTANTIATE_ABS(int);
3053 INSTANTIATE_ABS(long);
3054 INSTANTIATE_ABS(long long);
3055
3056 #define SPECIALIZE_UABS(T) \
3057 template <> \
3058 /* static */ inline unsigned T \
3059 abs (unsigned T x) \
3060 { \
3061 return x; \
3062 }
3063
3064 SPECIALIZE_UABS(char)
3065 SPECIALIZE_UABS(short)
3066 SPECIALIZE_UABS(int)
3067 SPECIALIZE_UABS(long)
3068 SPECIALIZE_UABS(long long)
3069
3070 template void
3071 pr_int (std::ostream&, const octave_int8&, int);
3072
3073 template void
3074 pr_int (std::ostream&, const octave_int16&, int);
3075
3076 template void
3077 pr_int (std::ostream&, const octave_int32&, int);
3078
3079 template void
3080 pr_int (std::ostream&, const octave_int64&, int);
3081
3082 template void
3083 pr_int (std::ostream&, const octave_uint8&, int);
3084
3085 template void
3086 pr_int (std::ostream&, const octave_uint16&, int);
3087
3088 template void
3089 pr_int (std::ostream&, const octave_uint32&, int);
3090
3091 template void
3092 pr_int (std::ostream&, const octave_uint64&, int);
3093
3094 template <class T>
3095 void
3096 octave_print_internal_template (std::ostream& os, const octave_int<T>& val,
3097 bool)
3098 {
3099 if (plus_format)
3100 {
3101 pr_plus_format (os, val);
3102 }
3103 else
3104 {
3105 if (free_format)
3106 os << typename octave_print_conv<octave_int<T> >::print_conv_type (val);
3107 else
3108 pr_int (os, val);
3109 }
3110 }
3111
3112 #define PRINT_INT_SCALAR_INTERNAL(TYPE) \
3113 OCTINTERP_API void \
3114 octave_print_internal (std::ostream& os, const octave_int<TYPE>& val, bool dummy) \
3115 { \
3116 octave_print_internal_template (os, val, dummy); \
3117 }
3118
3119 PRINT_INT_SCALAR_INTERNAL (int8_t)
3120 PRINT_INT_SCALAR_INTERNAL (uint8_t)
3121 PRINT_INT_SCALAR_INTERNAL (int16_t)
3122 PRINT_INT_SCALAR_INTERNAL (uint16_t)
3123 PRINT_INT_SCALAR_INTERNAL (int32_t)
3124 PRINT_INT_SCALAR_INTERNAL (uint32_t)
3125 PRINT_INT_SCALAR_INTERNAL (int64_t)
3126 PRINT_INT_SCALAR_INTERNAL (uint64_t)
3127
3128 template <class T>
3129 /* static */ inline void
3130 octave_print_internal_template (std::ostream& os, const intNDArray<T>& nda,
3131 bool pr_as_read_syntax, int extra_indent)
3132 {
3133 // FIXME -- this mostly duplicates the code in the print_nd_array<>
3134 // function. Can fix this with std::is_same from C++11.
3135
3136 if (nda.is_empty ())
3137 print_empty_nd_array (os, nda.dims (), pr_as_read_syntax);
3138 else if (nda.length () == 1)
3139 octave_print_internal_template (os, nda(0), pr_as_read_syntax);
3140 else if (plus_format && ! pr_as_read_syntax)
3141 {
3142 int ndims = nda.ndims ();
3143
3144 Array<octave_idx_type> ra_idx (dim_vector (ndims, 1), 0);
3145
3146 dim_vector dims = nda.dims ();
3147
3148 octave_idx_type m = 1;
3149
3150 for (int i = 2; i < ndims; i++)
3151 m *= dims(i);
3152
3153 octave_idx_type nr = dims(0);
3154 octave_idx_type nc = dims(1);
3155
3156 for (octave_idx_type i = 0; i < m; i++)
3157 {
3158 if (m > 1)
3159 {
3160 std::string nm = "ans(:,:,";
3161
3162 std::ostringstream buf;
3163
3164 for (int k = 2; k < ndims; k++)
3165 {
3166 buf << ra_idx(k) + 1;
3167
3168 if (k < ndims - 1)
3169 buf << ",";
3170 else
3171 buf << ")";
3172 }
3173
3174 nm += buf.str ();
3175
3176 os << nm << " =\n";
3177 if (! Vcompact_format)
3178 os << "\n";
3179 }
3180
3181 Array<idx_vector> idx (dim_vector (ndims, 1));
3182
3183 idx(0) = idx_vector (':');
3184 idx(1) = idx_vector (':');
3185
3186 for (int k = 2; k < ndims; k++)
3187 idx(k) = idx_vector (ra_idx(k));
3188
3189 Array<T> page (nda.index (idx), dim_vector (nr, nc));
3190
3191 for (octave_idx_type ii = 0; ii < nr; ii++)
3192 {
3193 for (octave_idx_type jj = 0; jj < nc; jj++)
3194 {
3195 octave_quit ();
3196
3197 pr_plus_format (os, page(ii,jj));
3198 }
3199
3200 if ((ii < nr - 1) || (i < m -1))
3201 os << "\n";
3202 }
3203
3204 if (i < m - 1)
3205 {
3206 os << "\n";
3207 increment_index (ra_idx, dims, 2);
3208 }
3209 }
3210 }
3211 else
3212 {
3213 int ndims = nda.ndims ();
3214
3215 dim_vector dims = nda.dims ();
3216
3217 Array<octave_idx_type> ra_idx (dim_vector (ndims, 1), 0);
3218
3219 octave_idx_type m = 1;
3220
3221 for (int i = 2; i < ndims; i++)
3222 m *= dims(i);
3223
3224 octave_idx_type nr = dims(0);
3225 octave_idx_type nc = dims(1);
3226
3227 int fw = 0;
3228 if (hex_format)
3229 fw = 2 * nda(0).byte_size ();
3230 else if (bit_format)
3231 fw = nda(0).nbits ();
3232 else
3233 {
3234 bool isneg = false;
3235 int digits = 0;
3236
3237 for (octave_idx_type i = 0; i < dims.numel (); i++)
3238 {
3239 int new_digits = static_cast<int>
3240 (gnulib::floor (log10 (double (abs (nda(i).value ()))) + 1.0));
3241
3242 if (new_digits > digits)
3243 digits = new_digits;
3244
3245 if (! isneg)
3246 isneg = (abs (nda(i).value ()) != nda(i).value ());
3247 }
3248
3249 fw = digits + isneg;
3250 }
3251
3252 int column_width = fw + (rat_format ? 0 : (bank_format ? 5 : 2));
3253 octave_idx_type total_width = nc * column_width;
3254 int max_width = command_editor::terminal_cols () - extra_indent;
3255 octave_idx_type inc = nc;
3256 if (total_width > max_width && Vsplit_long_rows)
3257 {
3258 inc = max_width / column_width;
3259 if (inc == 0)
3260 inc++;
3261 }
3262
3263 for (octave_idx_type i = 0; i < m; i++)
3264 {
3265 if (m > 1)
3266 {
3267 std::string nm = "ans(:,:,";
3268
3269 std::ostringstream buf;
3270
3271 for (int k = 2; k < ndims; k++)
3272 {
3273 buf << ra_idx(k) + 1;
3274
3275 if (k < ndims - 1)
3276 buf << ",";
3277 else
3278 buf << ")";
3279 }
3280
3281 nm += buf.str ();
3282
3283 os << nm << " =\n";
3284 if (! Vcompact_format)
3285 os << "\n";
3286 }
3287
3288 Array<idx_vector> idx (dim_vector (ndims, 1));
3289
3290 idx(0) = idx_vector (':');
3291 idx(1) = idx_vector (':');
3292
3293 for (int k = 2; k < ndims; k++)
3294 idx(k) = idx_vector (ra_idx(k));
3295
3296 Array<T> page (nda.index (idx), dim_vector (nr, nc));
3297
3298 if (free_format)
3299 {
3300 if (pr_as_read_syntax)
3301 os << "[\n";
3302
3303 for (octave_idx_type ii = 0; ii < nr; ii++)
3304 {
3305 for (octave_idx_type jj = 0; jj < nc; jj++)
3306 {
3307 octave_quit ();
3308 os << " ";
3309 os << typename octave_print_conv<T>::print_conv_type (page(ii,jj));
3310 }
3311 os << "\n";
3312 }
3313
3314 if (pr_as_read_syntax)
3315 os << "]";
3316 }
3317 else
3318 {
3319 octave_idx_type n_rows = page.rows ();
3320 octave_idx_type n_cols = page.cols ();
3321
3322 for (octave_idx_type col = 0; col < n_cols; col += inc)
3323 {
3324 octave_idx_type lim = col + inc < n_cols ? col + inc : n_cols;
3325
3326 pr_col_num_header (os, total_width, max_width, lim, col,
3327 extra_indent);
3328
3329 for (octave_idx_type ii = 0; ii < n_rows; ii++)
3330 {
3331 os << std::setw (extra_indent) << "";
3332
3333 for (octave_idx_type jj = col; jj < lim; jj++)
3334 {
3335 octave_quit ();
3336 os << " ";
3337 pr_int (os, page(ii,jj), fw);
3338 }
3339 if ((ii < n_rows - 1) || (i < m -1))
3340 os << "\n";
3341 }
3342 }
3343 }
3344
3345 if (i < m - 1)
3346 {
3347 os << "\n";
3348 increment_index (ra_idx, dims, 2);
3349 }
3350 }
3351 }
3352 }
3353
3354 #define PRINT_INT_ARRAY_INTERNAL(TYPE) \
3355 OCTINTERP_API void \
3356 octave_print_internal (std::ostream& os, const intNDArray<TYPE>& nda, \
3357 bool pr_as_read_syntax, int extra_indent) \
3358 { \
3359 octave_print_internal_template (os, nda, pr_as_read_syntax, extra_indent); \
3360 }
3361
3362 PRINT_INT_ARRAY_INTERNAL (octave_int8)
3363 PRINT_INT_ARRAY_INTERNAL (octave_uint8)
3364 PRINT_INT_ARRAY_INTERNAL (octave_int16)
3365 PRINT_INT_ARRAY_INTERNAL (octave_uint16)
3366 PRINT_INT_ARRAY_INTERNAL (octave_int32)
3367 PRINT_INT_ARRAY_INTERNAL (octave_uint32)
3368 PRINT_INT_ARRAY_INTERNAL (octave_int64)
3369 PRINT_INT_ARRAY_INTERNAL (octave_uint64)
3370
3371 void
3372 octave_print_internal (std::ostream&, const Cell&, bool, int, bool)
3373 {
3374 panic_impossible ();
3375 }
3376
3377 DEFUN (rats, args, nargout,
3378 "-*- texinfo -*-\n\
3379 @deftypefn {Built-in Function} {} rats (@var{x}, @var{len})\n\
3380 Convert @var{x} into a rational approximation represented as a string.\n\
3381 You can convert the string back into a matrix as follows:\n\
3382 \n\
3383 @example\n\
3384 @group\n\
3385 r = rats (hilb (4));\n\
3386 x = str2num (r)\n\
3387 @end group\n\
3388 @end example\n\
3389 \n\
3390 The optional second argument defines the maximum length of the string\n\
3391 representing the elements of @var{x}. By default @var{len} is 9.\n\
3392 @seealso{format, rat}\n\
3393 @end deftypefn")
3394 {
3395 octave_value retval;
3396
3397 int nargin = args.length ();
3398
3399 if (nargin < 1 || nargin > 2 || nargout > 1)
3400 print_usage ();
3401 else
3402 {
3403 unwind_protect frame;
3404
3405 frame.protect_var (rat_string_len);
3406
3407 rat_string_len = 9;
3408
3409 if (nargin == 2)
3410 rat_string_len = args(1).nint_value ();
3411
3412 if (! error_state)
3413 {
3414 octave_value arg = args(0);
3415
3416 if (arg.is_numeric_type ())
3417 {
3418 frame.protect_var (rat_format);
3419
3420 rat_format = true;
3421
3422 std::ostringstream buf;
3423 args(0).print (buf);
3424 std::string s = buf.str ();
3425
3426 std::list<std::string> lst;
3427
3428 size_t n = 0;
3429 size_t s_len = s.length ();
3430
3431 while (n < s_len)
3432 {
3433 size_t m = s.find ('\n', n);
3434
3435 if (m == std::string::npos)
3436 {
3437 lst.push_back (s.substr (n));
3438 break;
3439 }
3440 else
3441 {
3442 lst.push_back (s.substr (n, m - n));
3443 n = m + 1;
3444 }
3445 }
3446
3447 retval = string_vector (lst);
3448 }
3449 else
3450 error ("rats: X must be numeric");
3451 }
3452 }
3453
3454 return retval;
3455 }
3456
3457 DEFUN (disp, args, nargout,
3458 "-*- texinfo -*-\n\
3459 @deftypefn {Built-in Function} {} disp (@var{x})\n\
3460 Display the value of @var{x}. For example:\n\
3461 \n\
3462 @example\n\
3463 @group\n\
3464 disp (\"The value of pi is:\"), disp (pi)\n\
3465 \n\
3466 @print{} the value of pi is:\n\
3467 @print{} 3.1416\n\
3468 @end group\n\
3469 @end example\n\
3470 \n\
3471 @noindent\n\
3472 Note that the output from @code{disp} always ends with a newline.\n\
3473 \n\
3474 If an output value is requested, @code{disp} prints nothing and\n\
3475 returns the formatted output in a string.\n\
3476 @seealso{fdisp}\n\
3477 @end deftypefn")
3478 {
3479 octave_value_list retval;
3480
3481 int nargin = args.length ();
3482
3483 if (nargin == 1 && nargout < 2)
3484 {
3485 if (nargout == 0)
3486 args(0).print (octave_stdout);
3487 else
3488 {
3489 octave_value arg = args(0);
3490 std::ostringstream buf;
3491 arg.print (buf);
3492 retval = octave_value (buf.str (), arg.is_dq_string () ? '"' : '\'');
3493 }
3494 }
3495 else
3496 print_usage ();
3497
3498 return retval;
3499 }
3500
3501 DEFUN (fdisp, args, ,
3502 "-*- texinfo -*-\n\
3503 @deftypefn {Built-in Function} {} fdisp (@var{fid}, @var{x})\n\
3504 Display the value of @var{x} on the stream @var{fid}. For example:\n\
3505 \n\
3506 @example\n\
3507 @group\n\
3508 fdisp (stdout, \"The value of pi is:\"), fdisp (stdout, pi)\n\
3509 \n\
3510 @print{} the value of pi is:\n\
3511 @print{} 3.1416\n\
3512 @end group\n\
3513 @end example\n\
3514 \n\
3515 @noindent\n\
3516 Note that the output from @code{fdisp} always ends with a newline.\n\
3517 @seealso{disp}\n\
3518 @end deftypefn")
3519 {
3520 octave_value_list retval;
3521
3522 int nargin = args.length ();
3523
3524 if (nargin == 2)
3525 {
3526 int fid = octave_stream_list::get_file_number (args (0));
3527
3528 octave_stream os = octave_stream_list::lookup (fid, "fdisp");
3529
3530 if (! error_state)
3531 {
3532 std::ostream *osp = os.output_stream ();
3533
3534 if (osp)
3535 args(1).print (*osp);
3536 else
3537 error ("fdisp: stream FID not open for writing");
3538 }
3539 }
3540 else
3541 print_usage ();
3542
3543 return retval;
3544 }
3545
3546 /*
3547 %!test
3548 %! format short
3549 %! fd = tmpfile ();
3550 %! for r = [0, Inf -Inf, NaN]
3551 %! for i = [0, Inf -Inf, NaN]
3552 %! fdisp (fd, complex (r, i));
3553 %! endfor
3554 %! endfor
3555 %! fclose (fd);
3556
3557 %!test
3558 %! foo.real = pi * ones (3,20,3);
3559 %! foo.complex = pi * ones (3,20,3) + 1i;
3560 %! foo.char = repmat ("- Hello World -", [3, 20]);
3561 %! foo.cell = {foo.real, foo.complex, foo.char};
3562 %! fields = fieldnames (foo);
3563 %! for f = 1:numel (fields)
3564 %! format loose;
3565 %! loose = disp (foo.(fields{f}));
3566 %! format compact;
3567 %! compact = disp (foo.(fields{f}));
3568 %! expected = strrep (loose, "\n\n", "\n");
3569 %! assert (expected, compact);
3570 %! endfor
3571 */
3572
3573 static void
3574 init_format_state (void)
3575 {
3576 free_format = false;
3577 plus_format = false;
3578 rat_format = false;
3579 bank_format = false;
3580 hex_format = 0;
3581 bit_format = 0;
3582 Vcompact_format = false;
3583 print_e = false;
3584 print_big_e = false;
3585 print_g = false;
3586 print_eng = false;
3587 }
3588
3589 static void
3590 set_output_prec_and_fw (int prec, int fw)
3591 {
3592 Voutput_precision = prec;
3593 Voutput_max_field_width = fw;
3594 }
3595
3596 static void
3597 set_format_style (int argc, const string_vector& argv)
3598 {
3599 int idx = 1;
3600
3601 if (--argc > 0)
3602 {
3603 std::string arg = argv[idx++];
3604
3605 if (arg == "short")
3606 {
3607 if (--argc > 0)
3608 {
3609 arg = argv[idx++];
3610
3611 if (arg == "e")
3612 {
3613 init_format_state ();
3614 print_e = true;
3615 }
3616 else if (arg == "E")
3617 {
3618 init_format_state ();
3619 print_e = true;
3620 print_big_e = true;
3621 }
3622 else if (arg == "g")
3623 {
3624 init_format_state ();
3625 print_g = true;
3626 }
3627 else if (arg == "G")
3628 {
3629 init_format_state ();
3630 print_g = true;
3631 print_big_e = true;
3632 }
3633 else if (arg == "eng")
3634 {
3635 init_format_state ();
3636 print_eng = true;
3637 }
3638 else
3639 {
3640 error ("format: unrecognized option 'short %s'",
3641 arg.c_str ());
3642 return;
3643 }
3644 }
3645 else
3646 init_format_state ();
3647
3648 set_output_prec_and_fw (5, 10);
3649 }
3650 else if (arg == "long")
3651 {
3652 if (--argc > 0)
3653 {
3654 arg = argv[idx++];
3655
3656 if (arg == "e")
3657 {
3658 init_format_state ();
3659 print_e = true;
3660 }
3661 else if (arg == "E")
3662 {
3663 init_format_state ();
3664 print_e = true;
3665 print_big_e = true;
3666 }
3667 else if (arg == "g")
3668 {
3669 init_format_state ();
3670 print_g = true;
3671 }
3672 else if (arg == "G")
3673 {
3674 init_format_state ();
3675 print_g = true;
3676 print_big_e = true;
3677 }
3678 else if (arg == "eng")
3679 {
3680 init_format_state ();
3681 print_eng = true;
3682 }
3683 else
3684 {
3685 error ("format: unrecognized option 'long %s'",
3686 arg.c_str ());
3687 return;
3688 }
3689 }
3690 else
3691 init_format_state ();
3692
3693 set_output_prec_and_fw (15, 20);
3694 }
3695 else if (arg == "hex")
3696 {
3697 init_format_state ();
3698 hex_format = 1;
3699 }
3700 else if (arg == "native-hex")
3701 {
3702 init_format_state ();
3703 hex_format = 2;
3704 }
3705 else if (arg == "bit")
3706 {
3707 init_format_state ();
3708 bit_format = 1;
3709 }
3710 else if (arg == "native-bit")
3711 {
3712 init_format_state ();
3713 bit_format = 2;
3714 }
3715 else if (arg == "+" || arg == "plus")
3716 {
3717 if (--argc > 0)
3718 {
3719 arg = argv[idx++];
3720
3721 if (arg.length () == 3)
3722 plus_format_chars = arg;
3723 else
3724 {
3725 error ("format: invalid option for plus format");
3726 return;
3727 }
3728 }
3729 else
3730 plus_format_chars = "+ ";
3731
3732 init_format_state ();
3733 plus_format = true;
3734 }
3735 else if (arg == "rat")
3736 {
3737 init_format_state ();
3738 rat_format = true;
3739 }
3740 else if (arg == "bank")
3741 {
3742 init_format_state ();
3743 bank_format = true;
3744 }
3745 else if (arg == "free")
3746 {
3747 init_format_state ();
3748 free_format = true;
3749 }
3750 else if (arg == "none")
3751 {
3752 init_format_state ();
3753 free_format = true;
3754 }
3755 else if (arg == "compact")
3756 {
3757 Vcompact_format = true;
3758 }
3759 else if (arg == "loose")
3760 {
3761 Vcompact_format = false;
3762 }
3763 else
3764 error ("format: unrecognized format state '%s'", arg.c_str ());
3765 }
3766 else
3767 {
3768 init_format_state ();
3769 set_output_prec_and_fw (5, 10);
3770 }
3771 }
3772
3773 DEFUN (format, args, ,
3774 "-*- texinfo -*-\n\
3775 @deftypefn {Command} {} format\n\
3776 @deftypefnx {Command} {} format options\n\
3777 Reset or specify the format of the output produced by @code{disp} and\n\
3778 Octave's normal echoing mechanism. This command only affects the display\n\
3779 of numbers but not how they are stored or computed. To change the internal\n\
3780 representation from the default double use one of the conversion functions\n\
3781 such as @code{single}, @code{uint8}, @code{int64}, etc.\n\
3782 \n\
3783 By default, Octave displays 5 significant digits in a human readable form\n\
3784 (option @samp{short} paired with @samp{loose} format for matrices).\n\
3785 If @code{format} is invoked without any options, this default format\n\
3786 is restored.\n\
3787 \n\
3788 Valid formats for floating point numbers are listed in the following\n\
3789 table.\n\
3790 \n\
3791 @table @code\n\
3792 @item short\n\
3793 Fixed point format with 5 significant figures in a field that is a maximum\n\
3794 of 10 characters wide. (default).\n\
3795 \n\
3796 If Octave is unable to format a matrix so that columns line up on the\n\
3797 decimal point and all numbers fit within the maximum field width then\n\
3798 it switches to an exponential @samp{e} format.\n\
3799 \n\
3800 @item long\n\
3801 Fixed point format with 15 significant figures in a field that is a maximum\n\
3802 of 20 characters wide.\n\
3803 \n\
3804 As with the @samp{short} format, Octave will switch to an exponential\n\
3805 @samp{e} format if it is unable to format a matrix properly using the\n\
3806 current format.\n\
3807 \n\
3808 @item short e\n\
3809 @itemx long e\n\
3810 Exponential format. The number to be represented is split between a mantissa\n\
3811 and an exponent (power of 10). The mantissa has 5 significant digits in the\n\
3812 short format and 15 digits in the long format.\n\
3813 For example, with the @samp{short e} format, @code{pi} is displayed as\n\
3814 @code{3.1416e+00}.\n\
3815 \n\
3816 @item short E\n\
3817 @itemx long E\n\
3818 Identical to @samp{short e} or @samp{long e} but displays an uppercase\n\
3819 @samp{E} to indicate the exponent.\n\
3820 For example, with the @samp{long E} format, @code{pi} is displayed as\n\
3821 @code{3.14159265358979E+00}.\n\
3822 \n\
3823 @item short g\n\
3824 @itemx long g\n\
3825 Optimally choose between fixed point and exponential format based on\n\
3826 the magnitude of the number.\n\
3827 For example, with the @samp{short g} format,\n\
3828 @code{pi .^ [2; 4; 8; 16; 32]} is displayed as\n\
3829 \n\
3830 @example\n\
3831 @group\n\
3832 ans =\n\
3833 \n\
3834 9.8696\n\
3835 97.409\n\
3836 9488.5\n\
3837 9.0032e+07\n\
3838 8.1058e+15\n\
3839 @end group\n\
3840 @end example\n\
3841 \n\
3842 @item short eng\n\
3843 @itemx long eng\n\
3844 Identical to @samp{short e} or @samp{long e} but displays the value\n\
3845 using an engineering format, where the exponent is divisible by 3. For\n\
3846 example, with the @samp{short eng} format, @code{10 * pi} is displayed as\n\
3847 @code{31.4159e+00}.\n\
3848 \n\
3849 @item long G\n\
3850 @itemx short G\n\
3851 Identical to @samp{short g} or @samp{long g} but displays an uppercase\n\
3852 @samp{E} to indicate the exponent.\n\
3853 \n\
3854 @item free\n\
3855 @itemx none\n\
3856 Print output in free format, without trying to line up columns of\n\
3857 matrices on the decimal point. This also causes complex numbers to be\n\
3858 formatted as numeric pairs like this @samp{(0.60419, 0.60709)} instead\n\
3859 of like this @samp{0.60419 + 0.60709i}.\n\
3860 @end table\n\
3861 \n\
3862 The following formats affect all numeric output (floating point and\n\
3863 integer types).\n\
3864 \n\
3865 @table @code\n\
3866 @item +\n\
3867 @itemx + @var{chars}\n\
3868 @itemx plus\n\
3869 @itemx plus @var{chars}\n\
3870 Print a @samp{+} symbol for nonzero matrix elements and a space for zero\n\
3871 matrix elements. This format can be very useful for examining the\n\
3872 structure of a large sparse matrix.\n\
3873 \n\
3874 The optional argument @var{chars} specifies a list of 3 characters to use\n\
3875 for printing values greater than zero, less than zero and equal to zero.\n\
3876 For example, with the @samp{+ \"+-.\"} format, @code{[1, 0, -1; -1, 0, 1]}\n\
3877 is displayed as\n\
3878 \n\
3879 @example\n\
3880 @group\n\
3881 ans =\n\
3882 \n\
3883 +.-\n\
3884 -.+\n\
3885 @end group\n\
3886 @end example\n\
3887 \n\
3888 @item bank\n\
3889 Print in a fixed format with two digits to the right of the decimal\n\
3890 point.\n\
3891 \n\
3892 @item native-hex\n\
3893 Print the hexadecimal representation of numbers as they are stored in\n\
3894 memory. For example, on a workstation which stores 8 byte real values\n\
3895 in IEEE format with the least significant byte first, the value of\n\
3896 @code{pi} when printed in @code{native-hex} format is\n\
3897 @code{400921fb54442d18}.\n\
3898 \n\
3899 @item hex\n\
3900 The same as @code{native-hex}, but always print the most significant\n\
3901 byte first.\n\
3902 \n\
3903 @item native-bit\n\
3904 Print the bit representation of numbers as stored in memory.\n\
3905 For example, the value of @code{pi} is\n\
3906 \n\
3907 @example\n\
3908 @group\n\
3909 01000000000010010010000111111011\n\
3910 01010100010001000010110100011000\n\
3911 @end group\n\
3912 @end example\n\
3913 \n\
3914 (shown here in two 32 bit sections for typesetting purposes) when\n\
3915 printed in native-bit format on a workstation which stores 8 byte real values\n\
3916 in IEEE format with the least significant byte first.\n\
3917 \n\
3918 @item bit\n\
3919 The same as @code{native-bit}, but always print the most significant\n\
3920 bits first.\n\
3921 \n\
3922 @item rat\n\
3923 Print a rational approximation, i.e., values are approximated\n\
3924 as the ratio of small integers.\n\
3925 For example, with the @samp{rat} format,\n\
3926 @code{pi} is displayed as @code{355/113}.\n\
3927 @end table\n\
3928 \n\
3929 The following two options affect the display of all matrices.\n\
3930 \n\
3931 @table @code\n\
3932 @item compact\n\
3933 Remove blank lines around column number labels and between\n\
3934 matrices producing more compact output with more data per page.\n\
3935 \n\
3936 @item loose\n\
3937 Insert blank lines above and below column number labels and between matrices\n\
3938 to produce a more readable output with less data per page. (default).\n\
3939 @end table\n\
3940 @seealso{fixed_point_format, output_max_field_width, output_precision, split_long_rows, rats}\n\
3941 @end deftypefn")
3942 {
3943 octave_value_list retval;
3944
3945 int argc = args.length () + 1;
3946
3947 string_vector argv = args.make_argv ("format");
3948
3949 if (error_state)
3950 return retval;
3951
3952 set_format_style (argc, argv);
3953
3954 return retval;
3955 }
3956
3957 DEFUN (fixed_point_format, args, nargout,
3958 "-*- texinfo -*-\n\
3959 @deftypefn {Built-in Function} {@var{val} =} fixed_point_format ()\n\
3960 @deftypefnx {Built-in Function} {@var{old_val} =} fixed_point_format (@var{new_val})\n\
3961 @deftypefnx {Built-in Function} {} fixed_point_format (@var{new_val}, \"local\")\n\
3962 Query or set the internal variable that controls whether Octave will\n\
3963 use a scaled format to print matrix values such that the largest\n\
3964 element may be written with a single leading digit with the scaling\n\
3965 factor is printed on the first line of output. For example:\n\
3966 \n\
3967 @example\n\
3968 @group\n\
3969 octave:1> logspace (1, 7, 5)'\n\
3970 ans =\n\
3971 \n\
3972 1.0e+07 *\n\
3973 \n\
3974 0.00000\n\
3975 0.00003\n\
3976 0.00100\n\
3977 0.03162\n\
3978 1.00000\n\
3979 @end group\n\
3980 @end example\n\
3981 \n\
3982 @noindent\n\
3983 Notice that first value appears to be zero when it is actually 1. For\n\
3984 this reason, you should be careful when setting\n\
3985 @code{fixed_point_format} to a nonzero value.\n\
3986 \n\
3987 When called from inside a function with the \"local\" option, the variable is\n\
3988 changed locally for the function and any subroutines it calls. The original\n\
3989 variable value is restored when exiting the function.\n\
3990 @seealso{format, output_max_field_width, output_precision}\n\
3991 @end deftypefn")
3992 {
3993 return SET_INTERNAL_VARIABLE (fixed_point_format);
3994 }
3995
3996 DEFUN (print_empty_dimensions, args, nargout,
3997 "-*- texinfo -*-\n\
3998 @deftypefn {Built-in Function} {@var{val} =} print_empty_dimensions ()\n\
3999 @deftypefnx {Built-in Function} {@var{old_val} =} print_empty_dimensions (@var{new_val})\n\
4000 @deftypefnx {Built-in Function} {} print_empty_dimensions (@var{new_val}, \"local\")\n\
4001 Query or set the internal variable that controls whether the\n\
4002 dimensions of empty matrices are printed along with the empty matrix\n\
4003 symbol, @samp{[]}. For example, the expression\n\
4004 \n\
4005 @example\n\
4006 zeros (3, 0)\n\
4007 @end example\n\
4008 \n\
4009 @noindent\n\
4010 will print\n\
4011 \n\
4012 @example\n\
4013 ans = [](3x0)\n\
4014 @end example\n\
4015 \n\
4016 When called from inside a function with the \"local\" option, the variable is\n\
4017 changed locally for the function and any subroutines it calls. The original\n\
4018 variable value is restored when exiting the function.\n\
4019 @seealso{format}\n\
4020 @end deftypefn")
4021 {
4022 return SET_INTERNAL_VARIABLE (print_empty_dimensions);
4023 }
4024
4025 DEFUN (split_long_rows, args, nargout,
4026 "-*- texinfo -*-\n\
4027 @deftypefn {Built-in Function} {@var{val} =} split_long_rows ()\n\
4028 @deftypefnx {Built-in Function} {@var{old_val} =} split_long_rows (@var{new_val})\n\
4029 @deftypefnx {Built-in Function} {} split_long_rows (@var{new_val}, \"local\")\n\
4030 Query or set the internal variable that controls whether rows of a matrix\n\
4031 may be split when displayed to a terminal window. If the rows are split,\n\
4032 Octave will display the matrix in a series of smaller pieces, each of\n\
4033 which can fit within the limits of your terminal width and each set of\n\
4034 rows is labeled so that you can easily see which columns are currently\n\
4035 being displayed. For example:\n\
4036 \n\
4037 @example\n\
4038 @group\n\
4039 octave:13> rand (2,10)\n\
4040 ans =\n\
4041 \n\
4042 Columns 1 through 6:\n\
4043 \n\
4044 0.75883 0.93290 0.40064 0.43818 0.94958 0.16467\n\
4045 0.75697 0.51942 0.40031 0.61784 0.92309 0.40201\n\
4046 \n\
4047 Columns 7 through 10:\n\
4048 \n\
4049 0.90174 0.11854 0.72313 0.73326\n\
4050 0.44672 0.94303 0.56564 0.82150\n\
4051 @end group\n\
4052 @end example\n\
4053 \n\
4054 When called from inside a function with the \"local\" option, the variable is\n\
4055 changed locally for the function and any subroutines it calls. The original\n\
4056 variable value is restored when exiting the function.\n\
4057 @seealso{format}\n\
4058 @end deftypefn")
4059 {
4060 return SET_INTERNAL_VARIABLE (split_long_rows);
4061 }
4062
4063 DEFUN (output_max_field_width, args, nargout,
4064 "-*- texinfo -*-\n\
4065 @deftypefn {Built-in Function} {@var{val} =} output_max_field_width ()\n\
4066 @deftypefnx {Built-in Function} {@var{old_val} =} output_max_field_width (@var{new_val})\n\
4067 @deftypefnx {Built-in Function} {} output_max_field_width (@var{new_val}, \"local\")\n\
4068 Query or set the internal variable that specifies the maximum width\n\
4069 of a numeric output field.\n\
4070 \n\
4071 When called from inside a function with the \"local\" option, the variable is\n\
4072 changed locally for the function and any subroutines it calls. The original\n\
4073 variable value is restored when exiting the function.\n\
4074 @seealso{format, fixed_point_format, output_precision}\n\
4075 @end deftypefn")
4076 {
4077 return SET_INTERNAL_VARIABLE_WITH_LIMITS (output_max_field_width, 0,
4078 std::numeric_limits<int>::max ());
4079 }
4080
4081 DEFUN (output_precision, args, nargout,
4082 "-*- texinfo -*-\n\
4083 @deftypefn {Built-in Function} {@var{val} =} output_precision ()\n\
4084 @deftypefnx {Built-in Function} {@var{old_val} =} output_precision (@var{new_val})\n\
4085 @deftypefnx {Built-in Function} {} output_precision (@var{new_val}, \"local\")\n\
4086 Query or set the internal variable that specifies the minimum number of\n\
4087 significant figures to display for numeric output.\n\
4088 \n\
4089 When called from inside a function with the \"local\" option, the variable is\n\
4090 changed locally for the function and any subroutines it calls. The original\n\
4091 variable value is restored when exiting the function.\n\
4092 @seealso{format, fixed_point_format, output_max_field_width}\n\
4093 @end deftypefn")
4094 {
4095 return SET_INTERNAL_VARIABLE_WITH_LIMITS (output_precision, -1,
4096 std::numeric_limits<int>::max ());
4097 }