23 #if defined (HAVE_CONFIG_H)
50 #if ! defined (HAVE_CXX_BITWISE_OP_TEMPLATES)
57 T
operator() (
const T & op1,
const T & op2)
const {
return (op1 & op2); }
64 T
operator() (
const T & op1,
const T & op2)
const {
return (op1 | op2); }
71 T
operator() (
const T & op1,
const T & op2)
const {
return (op1 ^ op2); }
76 template <
typename OP,
typename T>
81 int nelx = x.
numel ();
82 int nely = y.
numel ();
84 bool is_scalar_op = (nelx == 1 || nely == 1);
89 bool is_array_op = (dvx == dvy);
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",
102 for (
int i = 0;
i < nelx;
i++)
104 for (
int k = 0;
k < nely;
k++)
116 template <
typename T>
120 if (fname ==
"bitand")
122 if (fname ==
"bitor")
173 if (! (arg0_is_int || arg1_is_int))
175 if (arg0_is_bool && arg1_is_bool)
182 else if (arg0_is_float && arg1_is_float)
189 else if (! (arg0_is_float || arg1_is_float))
198 int p = (arg0_is_float ? 1 : 0);
199 int q = (arg0_is_float ? 0 : 1);
209 int p = (arg0_is_int ? 1 : 0);
210 int q = (arg0_is_int ? 0 : 1);
214 if (
args(q).type_id () == octave_uint64_matrix::static_type_id ()
215 ||
args(q).type_id () == octave_uint64_scalar::static_type_id ())
220 retval =
bitopx (fname, x, y);
222 else if (
args(q).type_id () == octave_uint32_matrix::static_type_id ()
223 ||
args(q).type_id () == octave_uint32_scalar::static_type_id ())
228 retval =
bitopx (fname, x, y);
230 else if (
args(q).type_id () == octave_uint16_matrix::static_type_id ()
231 ||
args(q).type_id () == octave_uint16_scalar::static_type_id ())
236 retval =
bitopx (fname, x, y);
238 else if (
args(q).type_id () == octave_uint8_matrix::static_type_id ()
239 ||
args(q).type_id () == octave_uint8_scalar::static_type_id ())
244 retval =
bitopx (fname, x, y);
246 else if (
args(q).type_id () == octave_int64_matrix::static_type_id ()
247 ||
args(q).type_id () == octave_int64_scalar::static_type_id ())
252 retval =
bitopx (fname, x, y);
254 else if (
args(q).type_id () == octave_int32_matrix::static_type_id ()
255 ||
args(q).type_id () == octave_int32_scalar::static_type_id ())
260 retval =
bitopx (fname, x, y);
262 else if (
args(q).type_id () == octave_int16_matrix::static_type_id ()
263 ||
args(q).type_id () == octave_int16_scalar::static_type_id ())
268 retval =
bitopx (fname, x, y);
270 else if (
args(q).type_id () == octave_int8_matrix::static_type_id ()
271 ||
args(q).type_id () == octave_int8_scalar::static_type_id ())
276 retval =
bitopx (fname, x, y);
279 error (
"%s: invalid operand type", fname.c_str ());
282 else if (
args(0).class_name () ==
args(1).class_name ())
284 if (
args(0).type_id () == octave_uint64_matrix::static_type_id ()
285 ||
args(0).type_id () == octave_uint64_scalar::static_type_id ())
290 retval =
bitopx (fname, x, y);
292 else if (
args(0).type_id () == octave_uint32_matrix::static_type_id ()
293 ||
args(0).type_id () == octave_uint32_scalar::static_type_id ())
298 retval =
bitopx (fname, x, y);
300 else if (
args(0).type_id () == octave_uint16_matrix::static_type_id ()
301 ||
args(0).type_id () == octave_uint16_scalar::static_type_id ())
306 retval =
bitopx (fname, x, y);
308 else if (
args(0).type_id () == octave_uint8_matrix::static_type_id ()
309 ||
args(0).type_id () == octave_uint8_scalar::static_type_id ())
314 retval =
bitopx (fname, x, y);
316 else if (
args(0).type_id () == octave_int64_matrix::static_type_id ()
317 ||
args(0).type_id () == octave_int64_scalar::static_type_id ())
322 retval =
bitopx (fname, x, y);
324 else if (
args(0).type_id () == octave_int32_matrix::static_type_id ()
325 ||
args(0).type_id () == octave_int32_scalar::static_type_id ())
330 retval =
bitopx (fname, x, y);
332 else if (
args(0).type_id () == octave_int16_matrix::static_type_id ()
333 ||
args(0).type_id () == octave_int16_scalar::static_type_id ())
338 retval =
bitopx (fname, x, y);
340 else if (
args(0).type_id () == octave_int8_matrix::static_type_id ()
341 ||
args(0).type_id () == octave_int8_scalar::static_type_id ())
346 retval =
bitopx (fname, x, y);
349 error (
"%s: invalid operand type", fname.c_str ());
352 error (
"%s: must have matching operand types", fname.c_str ());
420 template <
typename T>
422 max_mantissa_value ()
424 return (static_cast<int64_t> (1) << std::numeric_limits<T>::digits) - 1;
435 return (static_cast<int64_t> (a) << n) & mask;
437 return (static_cast<int64_t> (a) >> -n) & mask;
439 return static_cast<int64_t
> (
a) & mask;
443 bitshift (
float a,
int n, int64_t mask)
450 return (static_cast<int64_t> (a) << n) & mask;
452 return (static_cast<int64_t> (a) >> -n) & mask;
454 return static_cast<int64_t
> (
a) & mask;
461 #define DO_BITSHIFT(T) \
464 if (! n.all_integers (d1, d2)) \
465 error ("bitshift: K must be a scalar or array of integers"); \
467 int m_nel = m.numel (); \
468 int n_nel = n.numel (); \
470 bool is_scalar_op = (m_nel == 1 || n_nel == 1); \
472 dim_vector m_dv = m.dims (); \
473 dim_vector n_dv = n.dims (); \
475 bool is_array_op = (m_dv == n_dv); \
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"); \
480 T ## NDArray result; \
483 result.resize (m_dv); \
485 result.resize (n_dv); \
487 for (int i = 0; i < m_nel; i++) \
489 for (int k = 0; k < n_nel; k++) \
490 if (static_cast<int> (n(k)) >= bits_in_type) \
493 result(i+k) = bitshift (m(i), static_cast<int> (n(k)), mask); \
495 if (static_cast<int> (n(i)) >= bits_in_type) \
498 result(i) = bitshift (m(i), static_cast<int> (n(i)), mask); \
502 #define DO_UBITSHIFT(T, N) \
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); \
516 #define DO_SBITSHIFT(T, N) \
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); \
527 mask = mask | octave_ ## T :: min (); \
567 if (nargin < 2 || nargin > 3)
570 NDArray n =
args(1).xarray_value (
"bitshift: K must be a scalar or array of integers");
579 error (
"bitshift: N must be a scalar integer");
581 nbits =
args(2).xint_value (
"bitshift: N must be an integer");
584 error (
"bitshift: N must be positive");
592 if (cname ==
"double")
594 static const int bits_in_mantissa
595 = std::numeric_limits<double>::digits;
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);
603 int bits_in_type =
sizeof (
double)
604 * std::numeric_limits<unsigned char>::digits;
608 else if (cname ==
"uint8")
610 else if (cname ==
"uint16")
612 else if (cname ==
"uint32")
614 else if (cname ==
"uint64")
616 else if (cname ==
"int8")
618 else if (cname ==
"int16")
620 else if (cname ==
"int32")
622 else if (cname ==
"int64")
624 else if (cname ==
"single")
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);
634 int bits_in_type =
sizeof (float)
635 * std::numeric_limits<unsigned char>::digits;
640 error (
"bitshift: not defined for %s objects", cname.c_str ());
673 int nargin =
args.length ();
680 cname =
args(0).xstring_value (
"flintmax: argument must be a string");
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));
687 error (
"flintmax: not defined for class '%s'", cname.c_str ());
738 int nargin =
args.length ();
745 cname =
args(0).xstring_value (
"intmax: argument must be a string");
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")
766 error (
"intmax: not defined for '%s' objects", cname.c_str ());
825 int nargin =
args.length ();
832 cname =
args(0).xstring_value (
"intmin: argument must be a string");
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")
853 error (
"intmin: not defined for '%s' objects", cname.c_str ());
887 if (
args.length () != 0)
T operator()(const T &op1, const T &op2) const
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)
T operator()(const T &op1, const T &op2) const
static std::string static_class_name(void)
OCTAVE_EXPORT octave_value_list isa nd deftypefn *return ovl(args(0).is_integer_type())
OCTINTERP_API void print_usage(void)
octave_idx_type numel(void) const
Number of elements in the array.
OCTAVE_EXPORT octave_value_list uint16
octave_idx_type length(void) const
octave_int< uint16_t > octave_uint16
#define DEFUN(name, args_name, nargout_name, doc)
void error(const char *fmt,...)
boolNDArray bool_array_value(bool warn=false) const
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
#define DO_SBITSHIFT(T, N)
const dim_vector & dims(void) const
Return a const-reference so that dims ()(i) works efficiently.
FloatNDArray float_array_value(bool frc_str_conv=false) const
static std::string static_class_name(void)
OCTAVE_EXPORT octave_value_list uint32
nd deftypefn *octave_map m
OCTAVE_EXPORT octave_value_list int16
octave_value bitop(const std::string &fname, const octave_value_list &args)
OCTAVE_EXPORT octave_value_list int32
static std::string static_class_name(void)
T operator()(const T &op1, const T &op2) const
octave_value bitopxx(const OP &op, const std::string &fname, const Array< T > &x, const Array< T > &y)
With real return the complex result
octave_int< uint32_t > octave_uint32
static int bitop_arg_is_float(const octave_value &arg)
OCTAVE_EXPORT octave_value_list int64
#define DO_UBITSHIFT(T, N)
N Dimensional Array with copy-on-write semantics.
charNDArray max(char d, const charNDArray &m)
T::size_type numel(const T &str)
NDArray array_value(bool frc_str_conv=false) const
=val(i)}if ode{val(i)}occurs in table i
octave_int< int64_t > octave_int64
issues an error eealso double
std::string class_name(void) const
the element is set to zero In other the statement xample y
static int bitop_arg_is_bool(const octave_value &arg)
octave_int< int16_t > octave_int16
static octave_idx_type dim_max(void)
static int bitop_arg_is_int(const octave_value &arg)
octave_int< uint8_t > octave_uint8
Vector representing the dimensions (size) of an Array.
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
F77_RET_T F77_REAL &F77_RET_T F77_DBLE &F77_RET_T F77_REAL &F77_RET_T F77_DBLE &F77_RET_T F77_REAL &F77_RET_T F77_DBLE &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 F77_REAL &F77_RET_T F77_DBLE &F77_RET_T F77_DBLE &F77_RET_T F77_REAL &F77_RET_T F77_REAL &F77_RET_T F77_DBLE &F77_RET_T const F77_DBLE F77_DBLE &F77_RET_T const F77_REAL F77_REAL &F77_RET_T F77_REAL F77_REAL &F77_RET_T F77_DBLE F77_DBLE &F77_RET_T const F77_DBLE * x
return octave_value(v1.char_array_value().concat(v2.char_array_value(), ra_idx),((a1.is_sq_string()||a2.is_sq_string())? '\'': '"'))
charNDArray min(char d, const charNDArray &m)
octave_int< int8_t > octave_int8