comparison libinterp/corefcn/bitfcns.cc @ 15195:2fc554ffbc28

split libinterp from src * libinterp: New directory. Move all files from src directory here except Makefile.am, main.cc, main-cli.cc, mkoctfile.in.cc, mkoctfilr.in.sh, octave-config.in.cc, octave-config.in.sh. * libinterp/Makefile.am: New file, extracted from src/Makefile.am. * src/Makefile.am: Delete everything except targets and definitions needed to build and link main and utility programs. * Makefile.am (SUBDIRS): Include libinterp in the list. * autogen.sh: Run config-module.sh in libinterp/dldfcn directory, not src/dldfcn directory. * configure.ac (AC_CONFIG_SRCDIR): Use libinterp/octave.cc, not src/octave.cc. (DL_LDFLAGS, LIBOCTINTERP): Use libinterp, not src. (AC_CONFIG_FILES): Include libinterp/Makefile in the list. * find-docstring-files.sh: Look in libinterp, not src. * gui/src/Makefile.am (liboctgui_la_CPPFLAGS): Find header files in libinterp, not src.
author John W. Eaton <jwe@octave.org>
date Sat, 18 Aug 2012 16:23:39 -0400
parents src/corefcn/bitfcns.cc@b62b0b85369c
children 06897f865f0b
comparison
equal deleted inserted replaced
15194:0f0b795044c3 15195:2fc554ffbc28
1 /*
2
3 Copyright (C) 2004-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 "str-vec.h"
28 #include "quit.h"
29
30 #include "defun.h"
31 #include "error.h"
32 #include "ov.h"
33 #include "ov-uint64.h"
34 #include "ov-uint32.h"
35 #include "ov-uint16.h"
36 #include "ov-uint8.h"
37 #include "ov-int64.h"
38 #include "ov-int32.h"
39 #include "ov-int16.h"
40 #include "ov-int8.h"
41 #include "ov-scalar.h"
42 #include "ov-re-mat.h"
43 #include "ov-bool.h"
44
45 #include <functional>
46
47 #if !defined (HAVE_CXX_BITWISE_OP_TEMPLATES)
48 namespace std
49 {
50 template <typename T>
51 struct bit_and
52 {
53 public:
54 T operator() (const T & op1, const T & op2) const { return (op1 & op2); }
55 };
56
57 template <typename T>
58 struct bit_or
59 {
60 public:
61 T operator() (const T & op1, const T & op2) const { return (op1 | op2); }
62 };
63
64 template <typename T>
65 struct bit_xor
66 {
67 public:
68 T operator() (const T & op1, const T & op2) const { return (op1 ^ op2); }
69 };
70 }
71 #endif
72
73 template <typename OP, typename T>
74 octave_value
75 bitopxx (const OP& op, const std::string& fname,
76 const Array<T>& x, const Array<T>& y)
77 {
78 int nelx = x.numel ();
79 int nely = y.numel ();
80
81 bool is_scalar_op = (nelx == 1 || nely == 1);
82
83 dim_vector dvx = x.dims ();
84 dim_vector dvy = y.dims ();
85
86 bool is_array_op = (dvx == dvy);
87
88 octave_value retval;
89 if (is_array_op || is_scalar_op)
90 {
91 Array<T> result;
92
93 if (nelx != 1)
94 result.resize (dvx);
95 else
96 result.resize (dvy);
97
98 for (int i = 0; i < nelx; i++)
99 if (is_scalar_op)
100 for (int k = 0; k < nely; k++)
101 result(i+k) = op (x(i), y(k));
102 else
103 result(i) = op (x(i), y(i));
104
105 retval = result;
106 }
107 else
108 error ("%s: size of X and Y must match, or one operand must be a scalar",
109 fname.c_str ());
110
111 return retval;
112 }
113
114 // Trampoline function, instantiates the proper template above, with
115 // reflective information hardwired. We can't hardwire this information
116 // in Fbitxxx DEFUNs below, because at that moment, we still don't have
117 // information about which integer types we need to instantiate.
118 template<typename T>
119 octave_value
120 bitopx (const std::string& fname, const Array<T>& x, const Array<T>& y)
121 {
122 if (fname == "bitand")
123 return bitopxx (std::bit_and<T>(), fname, x, y);
124 if (fname == "bitor")
125 return bitopxx (std::bit_or<T>(), fname, x, y);
126
127 //else (fname == "bitxor")
128 return bitopxx (std::bit_xor<T>(), fname, x, y);
129 }
130
131 octave_value
132 bitop (const std::string& fname, const octave_value_list& args)
133 {
134 octave_value retval;
135
136 int nargin = args.length ();
137
138 if (nargin == 2)
139 {
140 if ((args(0).class_name () == octave_scalar::static_class_name ())
141 || (args(0).class_name () == octave_bool::static_class_name ())
142 || (args(1).class_name () == octave_scalar::static_class_name ())
143 || (args(1).class_name () == octave_bool::static_class_name ()))
144 {
145 bool arg0_is_int = (args(0).class_name () !=
146 octave_scalar::static_class_name () &&
147 args(0).class_name () !=
148 octave_bool::static_class_name ());
149 bool arg1_is_int = (args(1).class_name () !=
150 octave_scalar::static_class_name () &&
151 args(1).class_name () !=
152 octave_bool::static_class_name ());
153
154 if (! (arg0_is_int || arg1_is_int))
155 {
156 uint64NDArray x (args(0).array_value ());
157 uint64NDArray y (args(1).array_value ());
158 if (! error_state)
159 retval = bitopx (fname, x, y).array_value ();
160 }
161 else
162 {
163 int p = (arg0_is_int ? 1 : 0);
164 int q = (arg0_is_int ? 0 : 1);
165
166 NDArray dx = args(p).array_value ();
167
168 if (args(q).type_id () == octave_uint64_matrix::static_type_id ()
169 || args(q).type_id () == octave_uint64_scalar::static_type_id ())
170 {
171 uint64NDArray x (dx);
172 uint64NDArray y = args(q).uint64_array_value ();
173 if (! error_state)
174 retval = bitopx (fname, x, y);
175 }
176 else if (args(q).type_id () == octave_uint32_matrix::static_type_id ()
177 || args(q).type_id () == octave_uint32_scalar::static_type_id ())
178 {
179 uint32NDArray x (dx);
180 uint32NDArray y = args(q).uint32_array_value ();
181 if (! error_state)
182 retval = bitopx (fname, x, y);
183 }
184 else if (args(q).type_id () == octave_uint16_matrix::static_type_id ()
185 || args(q).type_id () == octave_uint16_scalar::static_type_id ())
186 {
187 uint16NDArray x (dx);
188 uint16NDArray y = args(q).uint16_array_value ();
189 if (! error_state)
190 retval = bitopx (fname, x, y);
191 }
192 else if (args(q).type_id () == octave_uint8_matrix::static_type_id ()
193 || args(q).type_id () == octave_uint8_scalar::static_type_id ())
194 {
195 uint8NDArray x (dx);
196 uint8NDArray y = args(q).uint8_array_value ();
197 if (! error_state)
198 retval = bitopx (fname, x, y);
199 }
200 else if (args(q).type_id () == octave_int64_matrix::static_type_id ()
201 || args(q).type_id () == octave_int64_scalar::static_type_id ())
202 {
203 int64NDArray x (dx);
204 int64NDArray y = args(q).int64_array_value ();
205 if (! error_state)
206 retval = bitopx (fname, x, y);
207 }
208 else if (args(q).type_id () == octave_int32_matrix::static_type_id ()
209 || args(q).type_id () == octave_int32_scalar::static_type_id ())
210 {
211 int32NDArray x (dx);
212 int32NDArray y = args(q).int32_array_value ();
213 if (! error_state)
214 retval = bitopx (fname, x, y);
215 }
216 else if (args(q).type_id () == octave_int16_matrix::static_type_id ()
217 || args(q).type_id () == octave_int16_scalar::static_type_id ())
218 {
219 int16NDArray x (dx);
220 int16NDArray y = args(q).int16_array_value ();
221 if (! error_state)
222 retval = bitopx (fname, x, y);
223 }
224 else if (args(q).type_id () == octave_int8_matrix::static_type_id ()
225 || args(q).type_id () == octave_int8_scalar::static_type_id ())
226 {
227 int8NDArray x (dx);
228 int8NDArray y = args(q).int8_array_value ();
229 if (! error_state)
230 retval = bitopx (fname, x, y);
231 }
232 else
233 error ("%s: invalid operand type", fname.c_str ());
234 }
235 }
236 else if (args(0).class_name () == args(1).class_name ())
237 {
238 if (args(0).type_id () == octave_uint64_matrix::static_type_id ()
239 || args(0).type_id () == octave_uint64_scalar::static_type_id ())
240 {
241 uint64NDArray x = args(0).uint64_array_value ();
242 uint64NDArray y = args(1).uint64_array_value ();
243 if (! error_state)
244 retval = bitopx (fname, x, y);
245 }
246 else if (args(0).type_id () == octave_uint32_matrix::static_type_id ()
247 || args(0).type_id () == octave_uint32_scalar::static_type_id ())
248 {
249 uint32NDArray x = args(0).uint32_array_value ();
250 uint32NDArray y = args(1).uint32_array_value ();
251 if (! error_state)
252 retval = bitopx (fname, x, y);
253 }
254 else if (args(0).type_id () == octave_uint16_matrix::static_type_id ()
255 || args(0).type_id () == octave_uint16_scalar::static_type_id ())
256 {
257 uint16NDArray x = args(0).uint16_array_value ();
258 uint16NDArray y = args(1).uint16_array_value ();
259 if (! error_state)
260 retval = bitopx (fname, x, y);
261 }
262 else if (args(0).type_id () == octave_uint8_matrix::static_type_id ()
263 || args(0).type_id () == octave_uint8_scalar::static_type_id ())
264 {
265 uint8NDArray x = args(0).uint8_array_value ();
266 uint8NDArray y = args(1).uint8_array_value ();
267 if (! error_state)
268 retval = bitopx (fname, x, y);
269 }
270 else if (args(0).type_id () == octave_int64_matrix::static_type_id ()
271 || args(0).type_id () == octave_int64_scalar::static_type_id ())
272 {
273 int64NDArray x = args(0).int64_array_value ();
274 int64NDArray y = args(1).int64_array_value ();
275 if (! error_state)
276 retval = bitopx (fname, x, y);
277 }
278 else if (args(0).type_id () == octave_int32_matrix::static_type_id ()
279 || args(0).type_id () == octave_int32_scalar::static_type_id ())
280 {
281 int32NDArray x = args(0).int32_array_value ();
282 int32NDArray y = args(1).int32_array_value ();
283 if (! error_state)
284 retval = bitopx (fname, x, y);
285 }
286 else if (args(0).type_id () == octave_int16_matrix::static_type_id ()
287 || args(0).type_id () == octave_int16_scalar::static_type_id ())
288 {
289 int16NDArray x = args(0).int16_array_value ();
290 int16NDArray y = args(1).int16_array_value ();
291 if (! error_state)
292 retval = bitopx (fname, x, y);
293 }
294 else if (args(0).type_id () == octave_int8_matrix::static_type_id ()
295 || args(0).type_id () == octave_int8_scalar::static_type_id ())
296 {
297 int8NDArray x = args(0).int8_array_value ();
298 int8NDArray y = args(1).int8_array_value ();
299 if (! error_state)
300 retval = bitopx (fname, x, y);
301 }
302 else
303 error ("%s: invalid operand type", fname.c_str ());
304 }
305 else
306 error ("%s: must have matching operand types", fname.c_str ());
307 }
308 else
309 print_usage ();
310
311 return retval;
312 }
313
314 DEFUN (bitand, args, ,
315 "-*- texinfo -*-\n\
316 @deftypefn {Built-in Function} {} bitand (@var{x}, @var{y})\n\
317 Return the bitwise AND of non-negative integers.\n\
318 @var{x}, @var{y} must be in the range [0,bitmax]\n\
319 @seealso{bitor, bitxor, bitset, bitget, bitcmp, bitshift, bitmax}\n\
320 @end deftypefn")
321 {
322 return bitop ("bitand", args);
323 }
324
325 DEFUN (bitor, args, ,
326 "-*- texinfo -*-\n\
327 @deftypefn {Built-in Function} {} bitor (@var{x}, @var{y})\n\
328 Return the bitwise OR of non-negative integers.\n\
329 @var{x}, @var{y} must be in the range [0,bitmax]\n\
330 @seealso{bitor, bitxor, bitset, bitget, bitcmp, bitshift, bitmax}\n\
331 @end deftypefn")
332 {
333 return bitop ("bitor", args);
334 }
335
336 DEFUN (bitxor, args, ,
337 "-*- texinfo -*-\n\
338 @deftypefn {Built-in Function} {} bitxor (@var{x}, @var{y})\n\
339 Return the bitwise XOR of non-negative integers.\n\
340 @var{x}, @var{y} must be in the range [0,bitmax]\n\
341 @seealso{bitand, bitor, bitset, bitget, bitcmp, bitshift, bitmax}\n\
342 @end deftypefn")
343 {
344 return bitop ("bitxor", args);
345 }
346
347 static int64_t
348 bitshift (double a, int n, int64_t mask)
349 {
350 // In the name of bug-for-bug compatibility.
351 if (a < 0)
352 return -bitshift (-a, n, mask);
353
354 if (n > 0)
355 return (static_cast<int64_t> (a) << n) & mask;
356 else if (n < 0)
357 return (static_cast<int64_t> (a) >> -n) & mask;
358 else
359 return static_cast<int64_t> (a) & mask;
360 }
361
362 static int64_t
363 bitshift (float a, int n, int64_t mask)
364 {
365 // In the name of bug-for-bug compatibility.
366 if (a < 0)
367 return -bitshift (-a, n, mask);
368
369 if (n > 0)
370 return (static_cast<int64_t> (a) << n) & mask;
371 else if (n < 0)
372 return (static_cast<int64_t> (a) >> -n) & mask;
373 else
374 return static_cast<int64_t> (a) & mask;
375 }
376
377 // Note that the bitshift operators are undefined if shifted by more
378 // bits than in the type, so we need to test for the size of the
379 // shift.
380
381 #define DO_BITSHIFT(T) \
382 if (! error_state) \
383 { \
384 double d1, d2; \
385 \
386 if (n.all_integers (d1, d2)) \
387 { \
388 int m_nel = m.numel (); \
389 int n_nel = n.numel (); \
390 \
391 bool is_scalar_op = (m_nel == 1 || n_nel == 1); \
392 \
393 dim_vector m_dv = m.dims (); \
394 dim_vector n_dv = n.dims (); \
395 \
396 bool is_array_op = (m_dv == n_dv); \
397 \
398 if (is_array_op || is_scalar_op) \
399 { \
400 T ## NDArray result; \
401 \
402 if (m_nel != 1) \
403 result.resize (m_dv); \
404 else \
405 result.resize (n_dv); \
406 \
407 for (int i = 0; i < m_nel; i++) \
408 if (is_scalar_op) \
409 for (int k = 0; k < n_nel; k++) \
410 if (static_cast<int> (n(k)) >= bits_in_type) \
411 result(i+k) = 0; \
412 else \
413 result(i+k) = bitshift (m(i), static_cast<int> (n(k)), mask); \
414 else \
415 if (static_cast<int> (n(i)) >= bits_in_type) \
416 result(i) = 0; \
417 else \
418 result(i) = bitshift (m(i), static_cast<int> (n(i)), mask); \
419 \
420 retval = result; \
421 } \
422 else \
423 error ("bitshift: size of A and N must match, or one operand must be a scalar"); \
424 } \
425 else \
426 error ("bitshift: expecting integer as second argument"); \
427 }
428
429 #define DO_UBITSHIFT(T, N) \
430 do \
431 { \
432 int bits_in_type = octave_ ## T :: nbits (); \
433 T ## NDArray m = m_arg.T ## _array_value (); \
434 octave_ ## T mask = octave_ ## T::max (); \
435 if ((N) < bits_in_type) \
436 mask = bitshift (mask, (N) - bits_in_type); \
437 else if ((N) < 1) \
438 mask = 0; \
439 DO_BITSHIFT (T); \
440 } \
441 while (0)
442
443 #define DO_SBITSHIFT(T, N) \
444 do \
445 { \
446 int bits_in_type = octave_ ## T :: nbits (); \
447 T ## NDArray m = m_arg.T ## _array_value (); \
448 octave_ ## T mask = octave_ ## T::max (); \
449 if ((N) < bits_in_type) \
450 mask = bitshift (mask, (N) - bits_in_type); \
451 else if ((N) < 1) \
452 mask = 0; \
453 mask = mask | octave_ ## T :: min (); /* FIXME: 2's complement only? */ \
454 DO_BITSHIFT (T); \
455 } \
456 while (0)
457
458 DEFUN (bitshift, args, ,
459 "-*- texinfo -*-\n\
460 @deftypefn {Built-in Function} {} bitshift (@var{a}, @var{k})\n\
461 @deftypefnx {Built-in Function} {} bitshift (@var{a}, @var{k}, @var{n})\n\
462 Return a @var{k} bit shift of @var{n}-digit unsigned\n\
463 integers in @var{a}. A positive @var{k} leads to a left shift;\n\
464 A negative value to a right shift. If @var{n} is omitted it defaults\n\
465 to log2(bitmax)+1.\n\
466 @var{n} must be in the range [1,log2(bitmax)+1] usually [1,33].\n\
467 \n\
468 @example\n\
469 @group\n\
470 bitshift (eye (3), 1)\n\
471 @result{}\n\
472 @group\n\
473 2 0 0\n\
474 0 2 0\n\
475 0 0 2\n\
476 @end group\n\
477 \n\
478 bitshift (10, [-2, -1, 0, 1, 2])\n\
479 @result{} 2 5 10 20 40\n\
480 @c FIXME -- restore this example when third arg is allowed to be an array.\n\
481 @c\n\
482 @c\n\
483 @c bitshift ([1, 10], 2, [3,4])\n\
484 @c @result{} 4 8\n\
485 @end group\n\
486 @end example\n\
487 @seealso{bitand, bitor, bitxor, bitset, bitget, bitcmp, bitmax}\n\
488 @end deftypefn")
489 {
490 octave_value retval;
491
492 int nargin = args.length ();
493
494 if (nargin == 2 || nargin == 3)
495 {
496 int nbits = 64;
497
498 NDArray n = args(1).array_value ();
499
500 if (error_state)
501 error ("bitshift: expecting integer as second argument");
502 else
503 {
504 if (nargin == 3)
505 {
506 // FIXME -- for compatibility, we should accept an array
507 // or a scalar as the third argument.
508 if (args(2).numel () > 1)
509 error ("bitshift: N must be a scalar integer");
510 else
511 {
512 nbits = args(2).int_value ();
513
514 if (error_state)
515 error ("bitshift: N must be an integer");
516 else if (nbits < 0)
517 error ("bitshift: N must be positive");
518 }
519 }
520 }
521
522 if (error_state)
523 return retval;
524
525 octave_value m_arg = args(0);
526 std::string cname = m_arg.class_name ();
527
528 if (cname == "uint8")
529 DO_UBITSHIFT (uint8, nbits < 8 ? nbits : 8);
530 else if (cname == "uint16")
531 DO_UBITSHIFT (uint16, nbits < 16 ? nbits : 16);
532 else if (cname == "uint32")
533 DO_UBITSHIFT (uint32, nbits < 32 ? nbits : 32);
534 else if (cname == "uint64")
535 DO_UBITSHIFT (uint64, nbits < 64 ? nbits : 64);
536 else if (cname == "int8")
537 DO_SBITSHIFT (int8, nbits < 8 ? nbits : 8);
538 else if (cname == "int16")
539 DO_SBITSHIFT (int16, nbits < 16 ? nbits : 16);
540 else if (cname == "int32")
541 DO_SBITSHIFT (int32, nbits < 32 ? nbits : 32);
542 else if (cname == "int64")
543 DO_SBITSHIFT (int64, nbits < 64 ? nbits : 64);
544 else if (cname == "double")
545 {
546 nbits = (nbits < 53 ? nbits : 53);
547 int64_t mask = 0x1FFFFFFFFFFFFFLL;
548 if (nbits < 53)
549 mask = mask >> (53 - nbits);
550 else if (nbits < 1)
551 mask = 0;
552 int bits_in_type = 64;
553 NDArray m = m_arg.array_value ();
554 DO_BITSHIFT ( );
555 }
556 else
557 error ("bitshift: not defined for %s objects", cname.c_str ());
558 }
559 else
560 print_usage ();
561
562 return retval;
563 }
564
565 DEFUN (bitmax, args, ,
566 "-*- texinfo -*-\n\
567 @deftypefn {Built-in Function} {} bitmax ()\n\
568 @deftypefnx {Built-in Function} {} bitmax (\"double\")\n\
569 @deftypefnx {Built-in Function} {} bitmax (\"single\")\n\
570 Return the largest integer that can be represented within a floating point\n\
571 value. The default class is \"double\", but \"single\" is a valid option.\n\
572 On IEEE-754 compatible systems, @code{bitmax} is @w{@math{2^{53} - 1}}.\n\
573 @end deftypefn")
574 {
575 octave_value retval;
576 std::string cname = "double";
577 int nargin = args.length ();
578
579 if (nargin == 1 && args(0).is_string ())
580 cname = args(0).string_value ();
581 else if (nargin != 0)
582 {
583 print_usage ();
584 return retval;
585 }
586
587 if (cname == "double")
588 retval = (static_cast<double> (0x1FFFFFFFFFFFFFLL));
589 else if (cname == "single")
590 retval = (static_cast<double> (0xFFFFFFL));
591 else
592 error ("bitmax: not defined for class '%s'", cname.c_str ());
593
594 return retval;
595 }
596
597 DEFUN (intmax, args, ,
598 "-*- texinfo -*-\n\
599 @deftypefn {Built-in Function} {} intmax (@var{type})\n\
600 Return the largest integer that can be represented in an integer type.\n\
601 The variable @var{type} can be\n\
602 \n\
603 @table @code\n\
604 @item int8\n\
605 signed 8-bit integer.\n\
606 \n\
607 @item int16\n\
608 signed 16-bit integer.\n\
609 \n\
610 @item int32\n\
611 signed 32-bit integer.\n\
612 \n\
613 @item int64\n\
614 signed 64-bit integer.\n\
615 \n\
616 @item uint8\n\
617 unsigned 8-bit integer.\n\
618 \n\
619 @item uint16\n\
620 unsigned 16-bit integer.\n\
621 \n\
622 @item uint32\n\
623 unsigned 32-bit integer.\n\
624 \n\
625 @item uint64\n\
626 unsigned 64-bit integer.\n\
627 @end table\n\
628 \n\
629 The default for @var{type} is @code{uint32}.\n\
630 @seealso{intmin, bitmax}\n\
631 @end deftypefn")
632 {
633 octave_value retval;
634 std::string cname = "int32";
635 int nargin = args.length ();
636
637 if (nargin == 1 && args(0).is_string ())
638 cname = args(0).string_value ();
639 else if (nargin != 0)
640 {
641 print_usage ();
642 return retval;
643 }
644
645 if (cname == "uint8")
646 retval = octave_uint8 (std::numeric_limits<uint8_t>::max ());
647 else if (cname == "uint16")
648 retval = octave_uint16 (std::numeric_limits<uint16_t>::max ());
649 else if (cname == "uint32")
650 retval = octave_uint32 (std::numeric_limits<uint32_t>::max ());
651 else if (cname == "uint64")
652 retval = octave_uint64 (std::numeric_limits<uint64_t>::max ());
653 else if (cname == "int8")
654 retval = octave_int8 (std::numeric_limits<int8_t>::max ());
655 else if (cname == "int16")
656 retval = octave_int16 (std::numeric_limits<int16_t>::max ());
657 else if (cname == "int32")
658 retval = octave_int32 (std::numeric_limits<int32_t>::max ());
659 else if (cname == "int64")
660 retval = octave_int64 (std::numeric_limits<int64_t>::max ());
661 else
662 error ("intmax: not defined for '%s' objects", cname.c_str ());
663
664 return retval;
665 }
666
667 DEFUN (intmin, args, ,
668 "-*- texinfo -*-\n\
669 @deftypefn {Built-in Function} {} intmin (@var{type})\n\
670 Return the smallest integer that can be represented in an integer type.\n\
671 The variable @var{type} can be\n\
672 \n\
673 @table @code\n\
674 @item int8\n\
675 signed 8-bit integer.\n\
676 \n\
677 @item int16\n\
678 signed 16-bit integer.\n\
679 \n\
680 @item int32\n\
681 signed 32-bit integer.\n\
682 \n\
683 @item int64\n\
684 signed 64-bit integer.\n\
685 \n\
686 @item uint8\n\
687 unsigned 8-bit integer.\n\
688 \n\
689 @item uint16\n\
690 unsigned 16-bit integer.\n\
691 \n\
692 @item uint32\n\
693 unsigned 32-bit integer.\n\
694 \n\
695 @item uint64\n\
696 unsigned 64-bit integer.\n\
697 @end table\n\
698 \n\
699 The default for @var{type} is @code{uint32}.\n\
700 @seealso{intmax, bitmax}\n\
701 @end deftypefn")
702 {
703 octave_value retval;
704 std::string cname = "int32";
705 int nargin = args.length ();
706
707 if (nargin == 1 && args(0).is_string ())
708 cname = args(0).string_value ();
709 else if (nargin != 0)
710 {
711 print_usage ();
712 return retval;
713 }
714
715 if (cname == "uint8")
716 retval = octave_uint8 (std::numeric_limits<uint8_t>::min ());
717 else if (cname == "uint16")
718 retval = octave_uint16 (std::numeric_limits<uint16_t>::min ());
719 else if (cname == "uint32")
720 retval = octave_uint32 (std::numeric_limits<uint32_t>::min ());
721 else if (cname == "uint64")
722 retval = octave_uint64 (std::numeric_limits<uint64_t>::min ());
723 else if (cname == "int8")
724 retval = octave_int8 (std::numeric_limits<int8_t>::min ());
725 else if (cname == "int16")
726 retval = octave_int16 (std::numeric_limits<int16_t>::min ());
727 else if (cname == "int32")
728 retval = octave_int32 (std::numeric_limits<int32_t>::min ());
729 else if (cname == "int64")
730 retval = octave_int64 (std::numeric_limits<int64_t>::min ());
731 else
732 error ("intmin: not defined for '%s' objects", cname.c_str ());
733
734 return retval;
735 }
736
737 DEFUN (sizemax, args, ,
738 "-*- texinfo -*-\n\
739 @deftypefn {Built-in Function} {} sizemax ()\n\
740 Return the largest value allowed for the size of an array.\n\
741 If Octave is compiled with 64-bit indexing, the result is of class int64,\n\
742 otherwise it is of class int32. The maximum array size is slightly\n\
743 smaller than the maximum value allowable for the relevant class as reported\n\
744 by @code{intmax}.\n\
745 @seealso{intmax}\n\
746 @end deftypefn")
747 {
748 octave_value retval;
749
750 if (args.length () == 0)
751 retval = octave_int<octave_idx_type> (dim_vector::dim_max ());
752 else
753 print_usage ();
754
755 return retval;
756 }