GNU Octave  4.4.1
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
bitfcns.cc
Go to the documentation of this file.
1 /*
2 
3 Copyright (C) 2004-2018 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
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
11 
12 Octave is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License 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 <https://www.gnu.org/licenses/>.
20 
21 */
22 
23 #if defined (HAVE_CONFIG_H)
24 # include "config.h"
25 #endif
26 
27 #include <limits>
28 
29 #include "str-vec.h"
30 #include "quit.h"
31 
32 #include "defun.h"
33 #include "error.h"
34 #include "ov.h"
35 #include "ov-uint64.h"
36 #include "ov-uint32.h"
37 #include "ov-uint16.h"
38 #include "ov-uint8.h"
39 #include "ov-int64.h"
40 #include "ov-int32.h"
41 #include "ov-int16.h"
42 #include "ov-int8.h"
43 #include "ov-float.h"
44 #include "ov-scalar.h"
45 #include "ov-re-mat.h"
46 #include "ov-bool.h"
47 
48 #include <functional>
49 
50 #if ! defined (HAVE_CXX_BITWISE_OP_TEMPLATES)
51 namespace std
52 {
53  template <typename T>
54  struct bit_and
55  {
56  public:
57  T operator() (const T & op1, const T & op2) const { return (op1 & op2); }
58  };
59 
60  template <typename T>
61  struct bit_or
62  {
63  public:
64  T operator() (const T & op1, const T & op2) const { return (op1 | op2); }
65  };
66 
67  template <typename T>
68  struct bit_xor
69  {
70  public:
71  T operator() (const T & op1, const T & op2) const { return (op1 ^ op2); }
72  };
73 }
74 #endif
75 
76 template <typename OP, typename T>
78 bitopxx (const OP& op, const std::string& fname,
79  const Array<T>& x, const Array<T>& y)
80 {
81  int nelx = x.numel ();
82  int nely = y.numel ();
83 
84  bool is_scalar_op = (nelx == 1 || nely == 1);
85 
86  dim_vector dvx = x.dims ();
87  dim_vector dvy = y.dims ();
88 
89  bool is_array_op = (dvx == dvy);
90 
91  if (! is_array_op && ! is_scalar_op)
92  error ("%s: size of X and Y must match, or one operand must be a scalar",
93  fname.c_str ());
94 
96 
97  if (nelx != 1)
98  result.resize (dvx);
99  else
100  result.resize (dvy);
101 
102  for (int i = 0; i < nelx; i++)
103  if (is_scalar_op)
104  for (int k = 0; k < nely; k++)
105  result(i+k) = op (x(i), y(k));
106  else
107  result(i) = op (x(i), y(i));
108 
109  return result;
110 }
111 
112 // Trampoline function, instantiates the proper template above, with
113 // reflective information hardwired. We can't hardwire this information
114 // in Fbitxxx DEFUNs below, because at that moment, we still don't have
115 // information about which integer types we need to instantiate.
116 template <typename T>
118 bitopx (const std::string& fname, const Array<T>& x, const Array<T>& y)
119 {
120  if (fname == "bitand")
121  return bitopxx (std::bit_and<T>(), fname, x, y);
122  if (fname == "bitor")
123  return bitopxx (std::bit_or<T>(), fname, x, y);
124 
125  //else (fname == "bitxor")
126  return bitopxx (std::bit_xor<T>(), fname, x, y);
127 }
128 
129 static inline int
131 {
135 }
136 
137 static inline int
139 {
141 }
142 
143 static inline int
145 {
147 }
148 
151 {
152  if (args.length () != 2)
153  print_usage ();
154 
156 
157  if (args(0).class_name () == octave_scalar::static_class_name ()
158  || args(0).class_name () == octave_float_scalar::static_class_name ()
159  || args(0).class_name () == octave_bool::static_class_name ()
160  || args(1).class_name () == octave_scalar::static_class_name ()
161  || args(1).class_name () == octave_float_scalar::static_class_name ()
162  || args(1).class_name () == octave_bool::static_class_name ())
163  {
164  bool arg0_is_int = bitop_arg_is_int (args(0));
165  bool arg1_is_int = bitop_arg_is_int (args(1));
166 
167  bool arg0_is_bool = bitop_arg_is_bool (args(0));
168  bool arg1_is_bool = bitop_arg_is_bool (args(1));
169 
170  bool arg0_is_float = bitop_arg_is_float (args(0));
171  bool arg1_is_float = bitop_arg_is_float (args(1));
172 
173  if (! (arg0_is_int || arg1_is_int))
174  {
175  if (arg0_is_bool && arg1_is_bool)
176  {
177  boolNDArray x (args(0).bool_array_value ());
178  boolNDArray y (args(1).bool_array_value ());
179 
181  }
182  else if (arg0_is_float && arg1_is_float)
183  {
184  uint64NDArray x (args(0).float_array_value ());
185  uint64NDArray y (args(1).float_array_value ());
186 
188  }
189  else if (! (arg0_is_float || arg1_is_float))
190  {
191  uint64NDArray x (args(0).array_value ());
192  uint64NDArray y (args(1).array_value ());
193 
194  retval = bitopx (fname, x, y).array_value ();
195  }
196  else
197  {
198  int p = (arg0_is_float ? 1 : 0);
199  int q = (arg0_is_float ? 0 : 1);
200 
201  uint64NDArray x (args(p).array_value ());
202  uint64NDArray y (args(q).float_array_value ());
203 
205  }
206  }
207  else
208  {
209  int p = (arg0_is_int ? 1 : 0);
210  int q = (arg0_is_int ? 0 : 1);
211 
212  NDArray dx = args(p).array_value ();
213 
214  if (args(q).type_id () == octave_uint64_matrix::static_type_id ()
215  || args(q).type_id () == octave_uint64_scalar::static_type_id ())
216  {
217  uint64NDArray x (dx);
218  uint64NDArray y = args(q).uint64_array_value ();
219 
220  retval = bitopx (fname, x, y);
221  }
222  else if (args(q).type_id () == octave_uint32_matrix::static_type_id ()
223  || args(q).type_id () == octave_uint32_scalar::static_type_id ())
224  {
225  uint32NDArray x (dx);
226  uint32NDArray y = args(q).uint32_array_value ();
227 
228  retval = bitopx (fname, x, y);
229  }
230  else if (args(q).type_id () == octave_uint16_matrix::static_type_id ()
231  || args(q).type_id () == octave_uint16_scalar::static_type_id ())
232  {
233  uint16NDArray x (dx);
234  uint16NDArray y = args(q).uint16_array_value ();
235 
236  retval = bitopx (fname, x, y);
237  }
238  else if (args(q).type_id () == octave_uint8_matrix::static_type_id ()
239  || args(q).type_id () == octave_uint8_scalar::static_type_id ())
240  {
241  uint8NDArray x (dx);
242  uint8NDArray y = args(q).uint8_array_value ();
243 
244  retval = bitopx (fname, x, y);
245  }
246  else if (args(q).type_id () == octave_int64_matrix::static_type_id ()
247  || args(q).type_id () == octave_int64_scalar::static_type_id ())
248  {
249  int64NDArray x (dx);
250  int64NDArray y = args(q).int64_array_value ();
251 
252  retval = bitopx (fname, x, y);
253  }
254  else if (args(q).type_id () == octave_int32_matrix::static_type_id ()
255  || args(q).type_id () == octave_int32_scalar::static_type_id ())
256  {
257  int32NDArray x (dx);
258  int32NDArray y = args(q).int32_array_value ();
259 
260  retval = bitopx (fname, x, y);
261  }
262  else if (args(q).type_id () == octave_int16_matrix::static_type_id ()
263  || args(q).type_id () == octave_int16_scalar::static_type_id ())
264  {
265  int16NDArray x (dx);
266  int16NDArray y = args(q).int16_array_value ();
267 
268  retval = bitopx (fname, x, y);
269  }
270  else if (args(q).type_id () == octave_int8_matrix::static_type_id ()
271  || args(q).type_id () == octave_int8_scalar::static_type_id ())
272  {
273  int8NDArray x (dx);
274  int8NDArray y = args(q).int8_array_value ();
275 
276  retval = bitopx (fname, x, y);
277  }
278  else
279  error ("%s: invalid operand type", fname.c_str ());
280  }
281  }
282  else if (args(0).class_name () == args(1).class_name ())
283  {
284  if (args(0).type_id () == octave_uint64_matrix::static_type_id ()
285  || args(0).type_id () == octave_uint64_scalar::static_type_id ())
286  {
287  uint64NDArray x = args(0).uint64_array_value ();
288  uint64NDArray y = args(1).uint64_array_value ();
289 
290  retval = bitopx (fname, x, y);
291  }
292  else if (args(0).type_id () == octave_uint32_matrix::static_type_id ()
293  || args(0).type_id () == octave_uint32_scalar::static_type_id ())
294  {
295  uint32NDArray x = args(0).uint32_array_value ();
296  uint32NDArray y = args(1).uint32_array_value ();
297 
298  retval = bitopx (fname, x, y);
299  }
300  else if (args(0).type_id () == octave_uint16_matrix::static_type_id ()
301  || args(0).type_id () == octave_uint16_scalar::static_type_id ())
302  {
303  uint16NDArray x = args(0).uint16_array_value ();
304  uint16NDArray y = args(1).uint16_array_value ();
305 
306  retval = bitopx (fname, x, y);
307  }
308  else if (args(0).type_id () == octave_uint8_matrix::static_type_id ()
309  || args(0).type_id () == octave_uint8_scalar::static_type_id ())
310  {
311  uint8NDArray x = args(0).uint8_array_value ();
312  uint8NDArray y = args(1).uint8_array_value ();
313 
314  retval = bitopx (fname, x, y);
315  }
316  else if (args(0).type_id () == octave_int64_matrix::static_type_id ()
317  || args(0).type_id () == octave_int64_scalar::static_type_id ())
318  {
319  int64NDArray x = args(0).int64_array_value ();
320  int64NDArray y = args(1).int64_array_value ();
321 
322  retval = bitopx (fname, x, y);
323  }
324  else if (args(0).type_id () == octave_int32_matrix::static_type_id ()
325  || args(0).type_id () == octave_int32_scalar::static_type_id ())
326  {
327  int32NDArray x = args(0).int32_array_value ();
328  int32NDArray y = args(1).int32_array_value ();
329 
330  retval = bitopx (fname, x, y);
331  }
332  else if (args(0).type_id () == octave_int16_matrix::static_type_id ()
333  || args(0).type_id () == octave_int16_scalar::static_type_id ())
334  {
335  int16NDArray x = args(0).int16_array_value ();
336  int16NDArray y = args(1).int16_array_value ();
337 
338  retval = bitopx (fname, x, y);
339  }
340  else if (args(0).type_id () == octave_int8_matrix::static_type_id ()
341  || args(0).type_id () == octave_int8_scalar::static_type_id ())
342  {
343  int8NDArray x = args(0).int8_array_value ();
344  int8NDArray y = args(1).int8_array_value ();
345 
346  retval = bitopx (fname, x, y);
347  }
348  else
349  error ("%s: invalid operand type", fname.c_str ());
350  }
351  else
352  error ("%s: must have matching operand types", fname.c_str ());
353 
354  return retval;
355 }
356 
357 DEFUN (bitand, args, ,
358  doc: /* -*- texinfo -*-
359 @deftypefn {} {} bitand (@var{x}, @var{y})
360 Return the bitwise AND of non-negative integers.
361 
362 @var{x}, @var{y} must be in the range [0,intmax]
363 @seealso{bitor, bitxor, bitset, bitget, bitcmp, bitshift, intmax, flintmax}
364 @end deftypefn */)
365 {
366  return bitop ("bitand", args);
367 }
368 
369 /*
370 %!# Function bitand is tested as part of bitxor BIST tests
371 */
372 
373 DEFUN (bitor, args, ,
374  doc: /* -*- texinfo -*-
375 @deftypefn {} {} bitor (@var{x}, @var{y})
376 Return the bitwise OR of non-negative integers @var{x} and @var{y}.
377 
378 @seealso{bitor, bitxor, bitset, bitget, bitcmp, bitshift, intmax, flintmax}
379 @end deftypefn */)
380 {
381  return bitop ("bitor", args);
382 }
383 
384 /*
385 %!# Function bitor is tested as part of bitxor BIST tests
386 */
387 
388 DEFUN (bitxor, args, ,
389  doc: /* -*- texinfo -*-
390 @deftypefn {} {} bitxor (@var{x}, @var{y})
391 Return the bitwise XOR of non-negative integers @var{x} and @var{y}.
392 
393 @seealso{bitand, bitor, bitset, bitget, bitcmp, bitshift, intmax, flintmax}
394 @end deftypefn */)
395 {
396  return bitop ("bitxor", args);
397 }
398 
399 /*
400 %!assert (bitand (true, false), false)
401 %!assert (bitor (true, false), true)
402 %!assert (bitxor (true, false), true)
403 
404 %!assert (bitand (true, true), true)
405 %!assert (bitor (true, true), true)
406 %!assert (bitxor (true, true), false)
407 
408 %!assert (bitand (true, 5), 1)
409 
410 %!assert (bitand (true, false), false)
411 %!assert (bitand (true, true), true)
412 %!assert (bitand (true, false), false)
413 %!assert (bitand (true, false), false)
414 
415 ## Test idx_arg.length () == 0
416 %!error <size of X and Y must match> bitand ([0 0 0], [1 0])
417 %!error <size of X and Y must match> bitand ([0; 0; 0], [0 0 0])
418 */
419 
420 template <typename T>
421 static int64_t
422 max_mantissa_value ()
423 {
424  return (static_cast<int64_t> (1) << std::numeric_limits<T>::digits) - 1;
425 }
426 
427 static int64_t
428 bitshift (double a, int n, int64_t mask)
429 {
430  // In the name of bug-for-bug compatibility.
431  if (a < 0)
432  return -bitshift (-a, n, mask);
433 
434  if (n > 0)
435  return (static_cast<int64_t> (a) << n) & mask;
436  else if (n < 0)
437  return (static_cast<int64_t> (a) >> -n) & mask;
438  else
439  return static_cast<int64_t> (a) & mask;
440 }
441 
442 static int64_t
443 bitshift (float a, int n, int64_t mask)
444 {
445  // In the name of bug-for-bug compatibility.
446  if (a < 0)
447  return -bitshift (-a, n, mask);
448 
449  if (n > 0)
450  return (static_cast<int64_t> (a) << n) & mask;
451  else if (n < 0)
452  return (static_cast<int64_t> (a) >> -n) & mask;
453  else
454  return static_cast<int64_t> (a) & mask;
455 }
456 
457 // Note that the bitshift operators are undefined if shifted by more
458 // bits than in the type, so we need to test for the size of the
459 // shift.
460 
461 #define DO_BITSHIFT(T) \
462  double d1, d2; \
463  \
464  if (! n.all_integers (d1, d2)) \
465  error ("bitshift: K must be a scalar or array of integers"); \
466  \
467  int m_nel = m.numel (); \
468  int n_nel = n.numel (); \
469  \
470  bool is_scalar_op = (m_nel == 1 || n_nel == 1); \
471  \
472  dim_vector m_dv = m.dims (); \
473  dim_vector n_dv = n.dims (); \
474  \
475  bool is_array_op = (m_dv == n_dv); \
476  \
477  if (! is_array_op && ! is_scalar_op) \
478  error ("bitshift: size of A and N must match, or one operand must be a scalar"); \
479  \
480  T ## NDArray result; \
481  \
482  if (m_nel != 1) \
483  result.resize (m_dv); \
484  else \
485  result.resize (n_dv); \
486  \
487  for (int i = 0; i < m_nel; i++) \
488  if (is_scalar_op) \
489  for (int k = 0; k < n_nel; k++) \
490  if (static_cast<int> (n(k)) >= bits_in_type) \
491  result(i+k) = 0; \
492  else \
493  result(i+k) = bitshift (m(i), static_cast<int> (n(k)), mask); \
494  else \
495  if (static_cast<int> (n(i)) >= bits_in_type) \
496  result(i) = 0; \
497  else \
498  result(i) = bitshift (m(i), static_cast<int> (n(i)), mask); \
499  \
500  retval = result;
501 
502 #define DO_UBITSHIFT(T, N) \
503  do \
504  { \
505  int bits_in_type = octave_ ## T :: nbits (); \
506  T ## NDArray m = m_arg.T ## _array_value (); \
507  octave_ ## T mask = octave_ ## T::max (); \
508  if ((N) < bits_in_type) \
509  mask = bitshift (mask, (N) - bits_in_type); \
510  else if ((N) < 1) \
511  mask = 0; \
512  DO_BITSHIFT (T); \
513  } \
514  while (0)
515 
516 #define DO_SBITSHIFT(T, N) \
517  do \
518  { \
519  int bits_in_type = octave_ ## T :: nbits (); \
520  T ## NDArray m = m_arg.T ## _array_value (); \
521  octave_ ## T mask = octave_ ## T::max (); \
522  if ((N) < bits_in_type) \
523  mask = bitshift (mask, (N) - bits_in_type); \
524  else if ((N) < 1) \
525  mask = 0; \
526  /* FIXME: 2's complement only? */ \
527  mask = mask | octave_ ## T :: min (); \
528  DO_BITSHIFT (T); \
529  } \
530  while (0)
531 
532 DEFUN (bitshift, args, ,
533  doc: /* -*- texinfo -*-
534 @deftypefn {} {} bitshift (@var{a}, @var{k})
535 @deftypefnx {} {} bitshift (@var{a}, @var{k}, @var{n})
536 Return a @var{k} bit shift of @var{n}-digit unsigned integers in @var{a}.
537 
538 A positive @var{k} leads to a left shift; A negative value to a right shift.
539 
540 If @var{n} is omitted it defaults to 64.
541 @var{n} must be in the range [1,64].
542 
543 @example
544 @group
545 bitshift (eye (3), 1)
546 @result{}
547 @group
548 2 0 0
549 0 2 0
550 0 0 2
551 @end group
552 
553 bitshift (10, [-2, -1, 0, 1, 2])
554 @result{} 2 5 10 20 40
555 @c FIXME: restore this example when third arg is allowed to be an array.
556 @c
557 @c
558 @c bitshift ([1, 10], 2, [3,4])
559 @c @result{} 4 8
560 @end group
561 @end example
562 @seealso{bitand, bitor, bitxor, bitset, bitget, bitcmp, intmax, flintmax}
563 @end deftypefn */)
564 {
565  int nargin = args.length ();
566 
568  print_usage ();
569 
570  NDArray n = args(1).xarray_value ("bitshift: K must be a scalar or array of integers");
571 
572  int nbits = 64;
573 
574  if (nargin == 3)
575  {
576  // FIXME: for compatibility, we should accept an array or a scalar
577  // as the third argument.
578  if (args(2).numel () > 1)
579  error ("bitshift: N must be a scalar integer");
580 
581  nbits = args(2).xint_value ("bitshift: N must be an integer");
582 
583  if (nbits < 0)
584  error ("bitshift: N must be positive");
585  }
586 
588 
589  octave_value m_arg = args(0);
590  std::string cname = m_arg.class_name ();
591 
592  if (cname == "double")
593  {
594  static const int bits_in_mantissa
595  = std::numeric_limits<double>::digits;
596 
597  nbits = (nbits < bits_in_mantissa ? nbits : bits_in_mantissa);
598  int64_t mask = max_mantissa_value<double> ();
599  if (nbits < bits_in_mantissa)
600  mask = mask >> (bits_in_mantissa - nbits);
601  else if (nbits < 1)
602  mask = 0;
603  int bits_in_type = sizeof (double)
604  * std::numeric_limits<unsigned char>::digits;
605  NDArray m = m_arg.array_value ();
606  DO_BITSHIFT ();
607  }
608  else if (cname == "uint8")
609  DO_UBITSHIFT (uint8, nbits < 8 ? nbits : 8);
610  else if (cname == "uint16")
611  DO_UBITSHIFT (uint16, nbits < 16 ? nbits : 16);
612  else if (cname == "uint32")
613  DO_UBITSHIFT (uint32, nbits < 32 ? nbits : 32);
614  else if (cname == "uint64")
615  DO_UBITSHIFT (uint64, nbits < 64 ? nbits : 64);
616  else if (cname == "int8")
617  DO_SBITSHIFT (int8, nbits < 8 ? nbits : 8);
618  else if (cname == "int16")
619  DO_SBITSHIFT (int16, nbits < 16 ? nbits : 16);
620  else if (cname == "int32")
621  DO_SBITSHIFT (int32, nbits < 32 ? nbits : 32);
622  else if (cname == "int64")
623  DO_SBITSHIFT (int64, nbits < 64 ? nbits : 64);
624  else if (cname == "single")
625  {
626  static const int bits_in_mantissa
627  = std::numeric_limits<float>::digits;
628  nbits = (nbits < bits_in_mantissa ? nbits : bits_in_mantissa);
629  int64_t mask = max_mantissa_value<float> ();
630  if (nbits < bits_in_mantissa)
631  mask = mask >> (bits_in_mantissa - nbits);
632  else if (nbits < 1)
633  mask = 0;
634  int bits_in_type = sizeof (float)
635  * std::numeric_limits<unsigned char>::digits;
636  FloatNDArray m = m_arg.float_array_value ();
637  DO_BITSHIFT (Float);
638  }
639  else
640  error ("bitshift: not defined for %s objects", cname.c_str ());
641 
642  return retval;
643 }
644 
645 /*
646 %!assert (bitshift (uint8 (16), 1), uint8 ( 32))
647 %!assert (bitshift (uint16 (16), 2), uint16 ( 64))
648 %!assert (bitshift (uint32 (16), 3), uint32 (128))
649 %!assert (bitshift (uint64 (16), 4), uint64 (256))
650 %!assert (bitshift (uint8 (255), 1), uint8 (254))
651 
652 %!error <K must be a scalar or array of integers> bitshift (16, 1.5)
653 %!error bitshift (16, {1})
654 %!error <N must be a scalar integer> bitshift (10, [-2 -1 0 1 2], [1 1 1 1 1])
655 %!error <N must be positive> bitshift (10, [-2 -1 0 1 2], -1)
656 */
657 
658 DEFUN (flintmax, args, ,
659  doc: /* -*- texinfo -*-
660 @deftypefn {} {} flintmax ()
661 @deftypefnx {} {} flintmax ("double")
662 @deftypefnx {} {} flintmax ("single")
663 Return the largest integer that can be represented consecutively in a
664 floating point value.
665 
666 The default class is @qcode{"double"}, but @qcode{"single"} is a valid
667 option. On IEEE 754 compatible systems, @code{flintmax} is
668 @w{@math{2^{53}}} for @qcode{"double"} and @w{@math{2^{24}}} for
669 @qcode{"single"}.
670 @seealso{intmax, realmax, realmin}
671 @end deftypefn */)
672 {
673  int nargin = args.length ();
674 
675  if (nargin > 1)
676  print_usage ();
677 
678  std::string cname = "double";
679  if (nargin == 1)
680  cname = args(0).xstring_value ("flintmax: argument must be a string");
681 
682  if (cname == "double")
683  return ovl (static_cast<double> (max_mantissa_value<double> () + 1));
684  else if (cname == "single")
685  return ovl (static_cast<float> (max_mantissa_value<float> () + 1));
686  else
687  error ("flintmax: not defined for class '%s'", cname.c_str ());
688 }
689 
690 /*
691 %!assert (flintmax (), 2^53)
692 %!assert (flintmax ("double"), 2^53)
693 %!assert (flintmax ("single"), single (2^24))
694 
695 %!error flintmax (0)
696 %!error flintmax ("double", 0)
697 %!error flintmax ("int32")
698 %!error flintmax ("char")
699 */
700 
701 DEFUN (intmax, args, ,
702  doc: /* -*- texinfo -*-
703 @deftypefn {} {} intmax (@var{type})
704 Return the largest integer that can be represented in an integer type.
705 
706 The variable @var{type} can be
707 
708 @table @code
709 @item int8
710 signed 8-bit integer.
711 
712 @item int16
713 signed 16-bit integer.
714 
715 @item int32
716 signed 32-bit integer.
717 
718 @item int64
719 signed 64-bit integer.
720 
721 @item uint8
722 unsigned 8-bit integer.
723 
724 @item uint16
725 unsigned 16-bit integer.
726 
727 @item uint32
728 unsigned 32-bit integer.
729 
730 @item uint64
731 unsigned 64-bit integer.
732 @end table
733 
734 The default for @var{type} is @code{int32}.
735 @seealso{intmin, flintmax}
736 @end deftypefn */)
737 {
738  int nargin = args.length ();
739 
740  if (nargin > 1)
741  print_usage ();
742 
743  std::string cname = "int32";
744  if (nargin == 1)
745  cname = args(0).xstring_value ("intmax: argument must be a string");
746 
748 
749  if (cname == "uint8")
751  else if (cname == "uint16")
753  else if (cname == "uint32")
755  else if (cname == "uint64")
757  else if (cname == "int8")
759  else if (cname == "int16")
761  else if (cname == "int32")
763  else if (cname == "int64")
765  else
766  error ("intmax: not defined for '%s' objects", cname.c_str ());
767 
768  return retval;
769 }
770 
771 /*
772 %!assert (intmax (), int32 (2^31 - 1))
773 %!assert (intmax ("int8"), int8 (2^7 - 1))
774 %!assert (intmax ("uint8"), uint8 (2^8 - 1))
775 %!assert (intmax ("int16"), int16 (2^15 - 1))
776 %!assert (intmax ("uint16"), uint16 (2^16 - 1))
777 %!assert (intmax ("int32"), int32 (2^31 - 1))
778 %!assert (intmax ("uint32"), uint32 (2^32 - 1))
779 %!assert (intmax ("int64"), int64 (2^63 - 1))
780 %!assert (intmax ("uint64"), uint64 (2^64 - 1))
781 
782 %!error intmax (0)
783 %!error intmax ("int32", 0)
784 %!error intmax ("double")
785 %!error intmax ("char")
786 */
787 
788 DEFUN (intmin, args, ,
789  doc: /* -*- texinfo -*-
790 @deftypefn {} {} intmin (@var{type})
791 Return the smallest integer that can be represented in an integer type.
792 
793 The variable @var{type} can be
794 
795 @table @code
796 @item int8
797 signed 8-bit integer.
798 
799 @item int16
800 signed 16-bit integer.
801 
802 @item int32
803 signed 32-bit integer.
804 
805 @item int64
806 signed 64-bit integer.
807 
808 @item uint8
809 unsigned 8-bit integer.
810 
811 @item uint16
812 unsigned 16-bit integer.
813 
814 @item uint32
815 unsigned 32-bit integer.
816 
817 @item uint64
818 unsigned 64-bit integer.
819 @end table
820 
821 The default for @var{type} is @code{int32}.
822 @seealso{intmax, flintmax}
823 @end deftypefn */)
824 {
825  int nargin = args.length ();
826 
827  if (nargin > 1)
828  print_usage ();
829 
830  std::string cname = "int32";
831  if (nargin == 1)
832  cname = args(0).xstring_value ("intmin: argument must be a string");
833 
835 
836  if (cname == "uint8")
838  else if (cname == "uint16")
840  else if (cname == "uint32")
842  else if (cname == "uint64")
844  else if (cname == "int8")
846  else if (cname == "int16")
848  else if (cname == "int32")
850  else if (cname == "int64")
852  else
853  error ("intmin: not defined for '%s' objects", cname.c_str ());
854 
855  return retval;
856 }
857 
858 /*
859 %!assert (intmin (), int32 (-2^31))
860 %!assert (intmin ("int8"), int8 (-2^7))
861 %!assert (intmin ("uint8"), uint8 (-2^8))
862 %!assert (intmin ("int16"), int16 (-2^15))
863 %!assert (intmin ("uint16"), uint16 (-2^16))
864 %!assert (intmin ("int32"), int32 (-2^31))
865 %!assert (intmin ("uint32"), uint32 (-2^32))
866 %!assert (intmin ("int64"), int64 (-2^63))
867 %!assert (intmin ("uint64"), uint64 (-2^64))
868 
869 %!error intmin (0)
870 %!error intmin ("int32", 0)
871 %!error intmin ("double")
872 %!error intmin ("char")
873 */
874 
875 DEFUN (sizemax, args, ,
876  doc: /* -*- texinfo -*-
877 @deftypefn {} {} sizemax ()
878 Return the largest value allowed for the size of an array.
879 
880 If Octave is compiled with 64-bit indexing, the result is of class int64,
881 otherwise it is of class int32. The maximum array size is slightly
882 smaller than the maximum value allowable for the relevant class as reported
883 by @code{intmax}.
884 @seealso{intmax}
885 @end deftypefn */)
886 {
887  if (args.length () != 0)
888  print_usage ();
889 
891 }
892 
893 /*
894 %!assert (sizemax () >= (intmax ("int32") - 1))
895 
896 %!error sizemax (0)
897 */
template OCTAVE_API octave_int< int8_t > bitshift(const octave_int< int8_t > &, int, const octave_int< int8_t > &)
octave_int< uint64_t > octave_uint64
octave_value bitopx(const std::string &fname, const Array< T > &x, const Array< T > &y)
Definition: bitfcns.cc:118
fname
Definition: load-save.cc:767
static std::string static_class_name(void)
Definition: ov-bool.h:257
OCTINTERP_API void print_usage(void)
Definition: defun.cc:54
for large enough k
Definition: lu.cc:617
octave_int< uint16_t > octave_uint16
T operator()(const T &op1, const T &op2) const
Definition: bitfcns.cc:57
#define DEFUN(name, args_name, nargout_name, doc)
Macro to define a builtin function.
Definition: defun.h:53
void error(const char *fmt,...)
Definition: error.cc:578
STL namespace.
T operator()(const T &op1, const T &op2) const
Definition: bitfcns.cc:71
FloatNDArray float_array_value(bool frc_str_conv=false) const
Definition: ov.h:843
octave_value arg
Definition: pr-output.cc:3244
calling an anonymous function involves an overhead quite comparable to the overhead of an m file function Passing a handle to a built in function is because the interpreter is not involved in the internal loop For a
Definition: cellfun.cc:400
#define DO_SBITSHIFT(T, N)
static std::string static_class_name(void)
Definition: ov-scalar.h:272
Array< octave_value > array_value(void) const
Definition: ovl.h:86
#define DO_BITSHIFT(T)
octave_value retval
Definition: data.cc:6246
octave_value bitop(const std::string &fname, const octave_value_list &args)
Definition: bitfcns.cc:150
static std::string static_class_name(void)
Definition: ov-float.h:269
std::string class_name(void) const
Definition: ov.h:1291
T operator()(const T &op1, const T &op2) const
Definition: bitfcns.cc:64
octave_value bitopxx(const OP &op, const std::string &fname, const Array< T > &x, const Array< T > &y)
Definition: bitfcns.cc:78
With real return the complex result
Definition: data.cc:3260
octave_int< uint32_t > octave_uint32
static int bitop_arg_is_float(const octave_value &arg)
Definition: bitfcns.cc:144
#define DO_UBITSHIFT(T, N)
return octave_value(v1.char_array_value() . concat(v2.char_array_value(), ra_idx),((a1.is_sq_string()||a2.is_sq_string()) ? '\'' :'"'))
N Dimensional Array with copy-on-write semantics.
Definition: Array.h:125
charNDArray max(char d, const charNDArray &m)
Definition: chNDArray.cc:227
boolNDArray bool_array_value(bool warn=false) const
Definition: ov.h:872
T::size_type numel(const T &str)
Definition: oct-string.cc:61
OCTAVE_EXPORT octave_value_list isa nd deftypefn *return ovl(args(0).isinteger())
p
Definition: lu.cc:138
octave_int< int64_t > octave_int64
octave_idx_type length(void) const
Definition: ovl.h:96
the element is set to zero In other the statement xample y
Definition: data.cc:5264
static int bitop_arg_is_bool(const octave_value &arg)
Definition: bitfcns.cc:138
args.length() nargin
Definition: file-io.cc:589
for i
Definition: data.cc:5264
octave_int< int16_t > octave_int16
static octave_idx_type dim_max(void)
Definition: dim-vector.cc:47
static int bitop_arg_is_int(const octave_value &arg)
Definition: bitfcns.cc:130
octave_int< uint8_t > octave_uint8
Vector representing the dimensions (size) of an Array.
Definition: dim-vector.h:87
octave_int< int32_t > octave_int32
If this string is the system will ring the terminal sometimes it is useful to be able to print the original representation of the string
Definition: utils.cc:888
NDArray array_value(bool frc_str_conv=false) const
Definition: ov.h:840
F77_RET_T const F77_REAL const F77_REAL F77_REAL &F77_RET_T const F77_DBLE const F77_DBLE F77_DBLE &F77_RET_T const F77_DBLE F77_DBLE &F77_RET_T const F77_REAL F77_REAL &F77_RET_T const F77_DBLE * x
charNDArray min(char d, const charNDArray &m)
Definition: chNDArray.cc:204
octave_int< int8_t > octave_int8