26#if defined (HAVE_CONFIG_H)
53#if ! defined (HAVE_CXX_BITWISE_OP_TEMPLATES)
60 T
operator() (
const T& op1,
const T& op2)
const {
return (op1 & op2); }
67 T
operator() (
const T& op1,
const T& op2)
const {
return (op1 | op2); }
74 T
operator() (
const T& op1,
const T& op2)
const {
return (op1 ^ op2); }
81template <
typename OP,
typename T>
83bitopxx (
const OP& op,
const std::string& fname,
86 int nelx =
x.numel ();
87 int nely = y.
numel ();
89 bool is_scalar_op = (nelx == 1 || nely == 1);
94 bool is_array_op = (dvx == dvy);
96 if (! is_array_op && ! is_scalar_op)
97 error (
"%s: size of X and Y must match, or one operand must be a scalar",
107 for (
int i = 0; i < nelx; i++)
109 for (
int k = 0; k < nely; k++)
110 result(i+k) = op (
x(i), y(k));
112 result(i) = op (
x(i), y(i));
125 if (fname ==
"bitand")
127 if (fname ==
"bitor")
178 if (! (arg0_is_int || arg1_is_int))
180 if (arg0_is_bool && arg1_is_bool)
187 else if (arg0_is_float && arg1_is_float)
194 else if (! (arg0_is_float || arg1_is_float))
203 int p = (arg0_is_float ? 1 : 0);
204 int q = (arg0_is_float ? 0 : 1);
214 int p = (arg0_is_int ? 1 : 0);
215 int q = (arg0_is_int ? 0 : 1);
227 else if (args(q).type_id () == octave_uint32_matrix::static_type_id ()
228 || args(q).type_id () == octave_uint32_scalar::static_type_id ())
235 else if (args(q).type_id () == octave_uint16_matrix::static_type_id ()
236 || args(q).type_id () == octave_uint16_scalar::static_type_id ())
243 else if (args(q).type_id () == octave_uint8_matrix::static_type_id ()
244 || args(q).type_id () == octave_uint8_scalar::static_type_id ())
251 else if (args(q).type_id () == octave_int64_matrix::static_type_id ()
252 || args(q).type_id () == octave_int64_scalar::static_type_id ())
259 else if (args(q).type_id () == octave_int32_matrix::static_type_id ()
260 || args(q).type_id () == octave_int32_scalar::static_type_id ())
267 else if (args(q).type_id () == octave_int16_matrix::static_type_id ()
268 || args(q).type_id () == octave_int16_scalar::static_type_id ())
275 else if (args(q).type_id () == octave_int8_matrix::static_type_id ()
276 || args(q).type_id () == octave_int8_scalar::static_type_id ())
284 error (
"%s: invalid operand type", fname.c_str ());
287 else if (args(0).class_name () == args(1).class_name ())
297 else if (args(0).type_id () == octave_uint32_matrix::static_type_id ()
298 || args(0).type_id () == octave_uint32_scalar::static_type_id ())
305 else if (args(0).type_id () == octave_uint16_matrix::static_type_id ()
306 || args(0).type_id () == octave_uint16_scalar::static_type_id ())
313 else if (args(0).type_id () == octave_uint8_matrix::static_type_id ()
314 || args(0).type_id () == octave_uint8_scalar::static_type_id ())
321 else if (args(0).type_id () == octave_int64_matrix::static_type_id ()
322 || args(0).type_id () == octave_int64_scalar::static_type_id ())
329 else if (args(0).type_id () == octave_int32_matrix::static_type_id ()
330 || args(0).type_id () == octave_int32_scalar::static_type_id ())
337 else if (args(0).type_id () == octave_int16_matrix::static_type_id ()
338 || args(0).type_id () == octave_int16_scalar::static_type_id ())
345 else if (args(0).type_id () == octave_int8_matrix::static_type_id ()
346 || args(0).type_id () == octave_int8_scalar::static_type_id ())
354 error (
"%s: invalid operand type", fname.c_str ());
357 error (
"%s: must have matching operand types", fname.c_str ());
362DEFUN (bitand, args, ,
371 return bitop (
"bitand", args);
386 return bitop (
"bitor", args);
393DEFUN (bitxor, args, ,
401 return bitop (
"bitxor", args);
429 return (
static_cast<int64_t
> (1) << std::numeric_limits<T>::digits) - 1;
440 return (
static_cast<int64_t
> (a) << n) & mask;
442 return (
static_cast<int64_t
> (a) >> -n) & mask;
444 return static_cast<int64_t
> (a) & mask;
455 return (
static_cast<int64_t
> (a) << n) & mask;
457 return (
static_cast<int64_t
> (a) >> -n) & mask;
459 return static_cast<int64_t
> (a) & mask;
466#define DO_BITSHIFT(T) \
469 if (! n.all_integers (d1, d2)) \
470 error ("bitshift: K must be a scalar or array of integers"); \
472 int m_nel = m.numel (); \
473 int n_nel = n.numel (); \
475 bool is_scalar_op = (m_nel == 1 || n_nel == 1); \
477 dim_vector m_dv = m.dims (); \
478 dim_vector n_dv = n.dims (); \
480 bool is_array_op = (m_dv == n_dv); \
482 if (! is_array_op && ! is_scalar_op) \
483 error ("bitshift: size of A and N must match, or one operand must be a scalar"); \
485 T ## NDArray result; \
488 result.resize (m_dv); \
490 result.resize (n_dv); \
492 for (int i = 0; i < m_nel; i++) \
494 for (int k = 0; k < n_nel; k++) \
495 if (static_cast<int> (n(k)) >= bits_in_type) \
498 result(i+k) = bitshift (m(i), static_cast<int> (n(k)), mask); \
500 if (static_cast<int> (n(i)) >= bits_in_type) \
503 result(i) = bitshift (m(i), static_cast<int> (n(i)), mask); \
507#define DO_UBITSHIFT(T, N) \
510 int bits_in_type = octave_ ## T :: nbits (); \
511 T ## NDArray m = m_arg.T ## _array_value (); \
512 octave_ ## T mask = octave_ ## T::max (); \
513 if ((N) < bits_in_type) \
514 mask = bitshift (mask, (N) - bits_in_type); \
521#define DO_SBITSHIFT(T, N) \
524 int bits_in_type = octave_ ## T :: nbits (); \
525 T ## NDArray m = m_arg.T ## _array_value (); \
526 octave_ ## T mask = octave_ ## T::max (); \
527 if ((N) < bits_in_type) \
528 mask = bitshift (mask, (N) - bits_in_type); \
532 mask = mask | octave_ ## T :: min (); \
570 int nargin = args.length ();
572 if (nargin < 2 || nargin > 3)
575 NDArray n = args(1).xarray_value (
"bitshift: K must be a scalar or array of integers");
583 if (args(2).
numel () > 1)
584 error (
"bitshift: N must be a scalar integer");
586 nbits = args(2).xint_value (
"bitshift: N must be an integer");
589 error (
"bitshift: N must be positive");
597 if (cname ==
"double")
599 static const int bits_in_mantissa
600 = std::numeric_limits<double>::digits;
602 nbits = (nbits < bits_in_mantissa ? nbits : bits_in_mantissa);
603 int64_t mask = max_mantissa_value<double> ();
604 if (nbits < bits_in_mantissa)
605 mask = mask >> (bits_in_mantissa - nbits);
606 int bits_in_type =
sizeof (
double)
607 * std::numeric_limits<unsigned char>::digits;
611 else if (cname ==
"uint8")
613 else if (cname ==
"uint16")
615 else if (cname ==
"uint32")
617 else if (cname ==
"uint64")
619 else if (cname ==
"int8")
621 else if (cname ==
"int16")
623 else if (cname ==
"int32")
625 else if (cname ==
"int64")
627 else if (cname ==
"single")
629 static const int bits_in_mantissa
630 = std::numeric_limits<float>::digits;
631 nbits = (nbits < bits_in_mantissa ? nbits : bits_in_mantissa);
632 int64_t mask = max_mantissa_value<float> ();
633 if (nbits < bits_in_mantissa)
634 mask = mask >> (bits_in_mantissa - nbits);
635 int bits_in_type =
sizeof (
float)
636 * std::numeric_limits<unsigned char>::digits;
641 error (
"bitshift: not defined for %s objects", cname.c_str ());
688 int nargin = args.length ();
693 std::string cname =
"double";
696 if (args(0).is_string ())
697 cname = args(0).string_value ();
698 else if (args(0).isfloat ())
699 cname = args(0).class_name ();
701 error (
"intmin: argument must be a string or floating point variable");
704 if (cname ==
"double")
705 return ovl (
static_cast<double> (max_mantissa_value<double> () + 1));
706 else if (cname ==
"single")
707 return ovl (
static_cast<float> (max_mantissa_value<float> () + 1));
709 error (
"flintmax: not defined for class '%s'", cname.c_str ());
727DEFUN (intmax, args, ,
780 int nargin = args.length ();
785 std::string cname =
"int32";
788 if (args(0).is_string ())
789 cname = args(0).string_value ();
791 cname = args(0).class_name ();
793 error (
"intmax: argument must be a string or integer variable");
798 if (cname ==
"uint8")
800 else if (cname ==
"uint16")
802 else if (cname ==
"uint32")
804 else if (cname ==
"uint64")
806 else if (cname ==
"int8")
808 else if (cname ==
"int16")
810 else if (cname ==
"int32")
812 else if (cname ==
"int64")
815 error (
"intmax: not defined for '%s' objects", cname.c_str ());
841DEFUN (intmin, args, ,
894 int nargin = args.length ();
899 std::string cname =
"int32";
902 if (args(0).is_string ())
903 cname = args(0).string_value ();
905 cname = args(0).class_name ();
907 error (
"intmin: argument must be a string or integer variable");
912 if (cname ==
"uint8")
914 else if (cname ==
"uint16")
916 else if (cname ==
"uint32")
918 else if (cname ==
"uint64")
920 else if (cname ==
"int8")
922 else if (cname ==
"int16")
924 else if (cname ==
"int32")
926 else if (cname ==
"int64")
929 error (
"intmin: not defined for '%s' objects", cname.c_str ());
955DEFUN (sizemax, args, ,
967 if (args.length () != 0)
static int bitop_arg_is_float(const octave_value &arg)
octave_value bitop(const std::string &fname, const octave_value_list &args)
static int bitop_arg_is_bool(const octave_value &arg)
octave_value bitopx(const std::string &fname, const Array< T > &x, const Array< T > &y)
#define DO_UBITSHIFT(T, N)
OCTAVE_NAMESPACE_BEGIN octave_value bitopxx(const OP &op, const std::string &fname, const Array< T > &x, const Array< T > &y)
#define DO_SBITSHIFT(T, N)
static int64_t max_mantissa_value()
static int64_t bitshift(double a, int n, int64_t mask)
static int bitop_arg_is_int(const octave_value &arg)
charNDArray max(char d, const charNDArray &m)
charNDArray min(char d, const charNDArray &m)
octave_idx_type numel(void) const
Number of elements in the array.
const dim_vector & dims(void) const
Return a const-reference so that dims ()(i) works efficiently.
OCTARRAY_API void resize(const dim_vector &dv, const T &rfv)
Size of the specified dimension.
Vector representing the dimensions (size) of an Array.
static OCTAVE_API octave_idx_type dim_max(void)
static std::string static_class_name(void)
static std::string static_class_name(void)
static std::string static_class_name(void)
static int static_type_id(void)
static int static_type_id(void)
Array< octave_value > array_value(void) const
octave_idx_type length(void) const
boolNDArray bool_array_value(bool warn=false) const
std::string class_name(void) const
NDArray array_value(bool frc_str_conv=false) const
FloatNDArray float_array_value(bool frc_str_conv=false) const
OCTINTERP_API void print_usage(void)
#define DEFUN(name, args_name, nargout_name, doc)
Macro to define a builtin function.
void error(const char *fmt,...)
static uint64_t flintmax(void)
F77_RET_T const F77_DBLE * x
octave_int< uint32_t > octave_uint32
octave_int< int32_t > octave_int32
octave_int< int16_t > octave_int16
octave_int< int8_t > octave_int8
octave_int< int64_t > octave_int64
octave_int< uint64_t > octave_uint64
octave_int< uint16_t > octave_uint16
octave_int< uint8_t > octave_uint8
T::size_type numel(const T &str)
return octave_value(v1.char_array_value() . concat(v2.char_array_value(), ra_idx),((a1.is_sq_string()||a2.is_sq_string()) ? '\'' :'"'))
octave_value_list ovl(const OV_Args &... args)
Construct an octave_value_list with less typing.
T operator()(const T &op1, const T &op2) const
T operator()(const T &op1, const T &op2) const
T operator()(const T &op1, const T &op2) const