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); }
79 template <
typename OP,
typename T>
81 bitopxx (
const OP& op,
const std::string& fname,
84 int nelx =
x.numel ();
85 int nely = y.
numel ();
87 bool is_scalar_op = (nelx == 1 || nely == 1);
92 bool is_array_op = (dvx == dvy);
94 if (! is_array_op && ! is_scalar_op)
95 error (
"%s: size of X and Y must match, or one operand must be a scalar",
105 for (
int i = 0; i < nelx; i++)
107 for (
int k = 0; k < nely; k++)
108 result(i+k) = op (
x(i), y(k));
110 result(i) = op (
x(i), y(i));
119 template <
typename T>
123 if (fname ==
"bitand")
125 if (fname ==
"bitor")
176 if (! (arg0_is_int || arg1_is_int))
178 if (arg0_is_bool && arg1_is_bool)
185 else if (arg0_is_float && arg1_is_float)
192 else if (! (arg0_is_float || arg1_is_float))
201 int p = (arg0_is_float ? 1 : 0);
202 int q = (arg0_is_float ? 0 : 1);
212 int p = (arg0_is_int ? 1 : 0);
213 int q = (arg0_is_int ? 0 : 1);
225 else if (args(q).type_id () == octave_uint32_matrix::static_type_id ()
226 || args(q).type_id () == octave_uint32_scalar::static_type_id ())
233 else if (args(q).type_id () == octave_uint16_matrix::static_type_id ()
234 || args(q).type_id () == octave_uint16_scalar::static_type_id ())
241 else if (args(q).type_id () == octave_uint8_matrix::static_type_id ()
242 || args(q).type_id () == octave_uint8_scalar::static_type_id ())
249 else if (args(q).type_id () == octave_int64_matrix::static_type_id ()
250 || args(q).type_id () == octave_int64_scalar::static_type_id ())
257 else if (args(q).type_id () == octave_int32_matrix::static_type_id ()
258 || args(q).type_id () == octave_int32_scalar::static_type_id ())
265 else if (args(q).type_id () == octave_int16_matrix::static_type_id ()
266 || args(q).type_id () == octave_int16_scalar::static_type_id ())
273 else if (args(q).type_id () == octave_int8_matrix::static_type_id ()
274 || args(q).type_id () == octave_int8_scalar::static_type_id ())
282 error (
"%s: invalid operand type", fname.c_str ());
285 else if (args(0).class_name () == args(1).class_name ())
295 else if (args(0).type_id () == octave_uint32_matrix::static_type_id ()
296 || args(0).type_id () == octave_uint32_scalar::static_type_id ())
303 else if (args(0).type_id () == octave_uint16_matrix::static_type_id ()
304 || args(0).type_id () == octave_uint16_scalar::static_type_id ())
311 else if (args(0).type_id () == octave_uint8_matrix::static_type_id ()
312 || args(0).type_id () == octave_uint8_scalar::static_type_id ())
319 else if (args(0).type_id () == octave_int64_matrix::static_type_id ()
320 || args(0).type_id () == octave_int64_scalar::static_type_id ())
327 else if (args(0).type_id () == octave_int32_matrix::static_type_id ()
328 || args(0).type_id () == octave_int32_scalar::static_type_id ())
335 else if (args(0).type_id () == octave_int16_matrix::static_type_id ()
336 || args(0).type_id () == octave_int16_scalar::static_type_id ())
343 else if (args(0).type_id () == octave_int8_matrix::static_type_id ()
344 || args(0).type_id () == octave_int8_scalar::static_type_id ())
352 error (
"%s: invalid operand type", fname.c_str ());
355 error (
"%s: must have matching operand types", fname.c_str ());
360 DEFUN (bitand, args, ,
369 return bitop (
"bitand", args);
376 DEFUN (bitor, args, ,
384 return bitop (
"bitor", args);
391 DEFUN (bitxor, args, ,
399 return bitop (
"bitxor", args);
423 template <
typename T>
427 return (
static_cast<int64_t
> (1) << std::numeric_limits<T>::digits) - 1;
438 return (
static_cast<int64_t
> (a) <<
n) & mask;
440 return (
static_cast<int64_t
> (a) >> -
n) & mask;
442 return static_cast<int64_t
> (a) & mask;
453 return (
static_cast<int64_t
> (a) <<
n) & mask;
455 return (
static_cast<int64_t
> (a) >> -
n) & mask;
457 return static_cast<int64_t
> (a) & mask;
464 #define DO_BITSHIFT(T) \
467 if (! n.all_integers (d1, d2)) \
468 error ("bitshift: K must be a scalar or array of integers"); \
470 int m_nel = m.numel (); \
471 int n_nel = n.numel (); \
473 bool is_scalar_op = (m_nel == 1 || n_nel == 1); \
475 dim_vector m_dv = m.dims (); \
476 dim_vector n_dv = n.dims (); \
478 bool is_array_op = (m_dv == n_dv); \
480 if (! is_array_op && ! is_scalar_op) \
481 error ("bitshift: size of A and N must match, or one operand must be a scalar"); \
483 T ## NDArray result; \
486 result.resize (m_dv); \
488 result.resize (n_dv); \
490 for (int i = 0; i < m_nel; i++) \
492 for (int k = 0; k < n_nel; k++) \
493 if (static_cast<int> (n(k)) >= bits_in_type) \
496 result(i+k) = bitshift (m(i), static_cast<int> (n(k)), mask); \
498 if (static_cast<int> (n(i)) >= bits_in_type) \
501 result(i) = bitshift (m(i), static_cast<int> (n(i)), mask); \
505 #define DO_UBITSHIFT(T, N) \
508 int bits_in_type = octave_ ## T :: nbits (); \
509 T ## NDArray m = m_arg.T ## _array_value (); \
510 octave_ ## T mask = octave_ ## T::max (); \
511 if ((N) < bits_in_type) \
512 mask = bitshift (mask, (N) - bits_in_type); \
519 #define DO_SBITSHIFT(T, N) \
522 int bits_in_type = octave_ ## T :: nbits (); \
523 T ## NDArray m = m_arg.T ## _array_value (); \
524 octave_ ## T mask = octave_ ## T::max (); \
525 if ((N) < bits_in_type) \
526 mask = bitshift (mask, (N) - bits_in_type); \
530 mask = mask | octave_ ## T :: min (); \
568 int nargin = args.length ();
570 if (nargin < 2 || nargin > 3)
573 NDArray n = args(1).xarray_value (
"bitshift: K must be a scalar or array of integers");
581 if (args(2).
numel () > 1)
582 error (
"bitshift: N must be a scalar integer");
584 nbits = args(2).xint_value (
"bitshift: N must be an integer");
587 error (
"bitshift: N must be positive");
595 if (cname ==
"double")
597 static const int bits_in_mantissa
598 = std::numeric_limits<double>::digits;
600 nbits = (nbits < bits_in_mantissa ? nbits : bits_in_mantissa);
601 int64_t mask = max_mantissa_value<double> ();
602 if (nbits < bits_in_mantissa)
603 mask = mask >> (bits_in_mantissa - nbits);
604 int bits_in_type =
sizeof (double)
605 * std::numeric_limits<unsigned char>::digits;
609 else if (cname ==
"uint8")
611 else if (cname ==
"uint16")
613 else if (cname ==
"uint32")
615 else if (cname ==
"uint64")
617 else if (cname ==
"int8")
619 else if (cname ==
"int16")
621 else if (cname ==
"int32")
623 else if (cname ==
"int64")
625 else if (cname ==
"single")
627 static const int bits_in_mantissa
628 = std::numeric_limits<float>::digits;
629 nbits = (nbits < bits_in_mantissa ? nbits : bits_in_mantissa);
630 int64_t mask = max_mantissa_value<float> ();
631 if (nbits < bits_in_mantissa)
632 mask = mask >> (bits_in_mantissa - nbits);
633 int bits_in_type =
sizeof (float)
634 * std::numeric_limits<unsigned char>::digits;
639 error (
"bitshift: not defined for %s objects", cname.c_str ());
657 DEFUN (flintmax, args, ,
686 int nargin = args.length ();
691 std::string cname =
"double";
694 if (args(0).is_string ())
695 cname = args(0).string_value ();
696 else if (args(0).isfloat ())
697 cname = args(0).class_name ();
699 error (
"intmin: argument must be a string or floating point variable");
702 if (cname ==
"double")
703 return ovl (
static_cast<double> (max_mantissa_value<double> () + 1));
704 else if (cname ==
"single")
705 return ovl (
static_cast<float> (max_mantissa_value<float> () + 1));
707 error (
"flintmax: not defined for class '%s'", cname.c_str ());
725 DEFUN (intmax, args, ,
778 int nargin = args.length ();
783 std::string cname =
"int32";
786 if (args(0).is_string ())
787 cname = args(0).string_value ();
789 cname = args(0).class_name ();
791 error (
"intmax: argument must be a string or integer variable");
796 if (cname ==
"uint8")
798 else if (cname ==
"uint16")
800 else if (cname ==
"uint32")
802 else if (cname ==
"uint64")
804 else if (cname ==
"int8")
806 else if (cname ==
"int16")
808 else if (cname ==
"int32")
810 else if (cname ==
"int64")
813 error (
"intmax: not defined for '%s' objects", cname.c_str ());
839 DEFUN (intmin, args, ,
892 int nargin = args.length ();
897 std::string cname =
"int32";
900 if (args(0).is_string ())
901 cname = args(0).string_value ();
903 cname = args(0).class_name ();
905 error (
"intmin: argument must be a string or integer variable");
910 if (cname ==
"uint8")
912 else if (cname ==
"uint16")
914 else if (cname ==
"uint32")
916 else if (cname ==
"uint64")
918 else if (cname ==
"int8")
920 else if (cname ==
"int16")
922 else if (cname ==
"int32")
924 else if (cname ==
"int64")
927 error (
"intmin: not defined for '%s' objects", cname.c_str ());
953 DEFUN (sizemax, args, ,
965 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)
octave_value bitopxx(const OP &op, const std::string &fname, const Array< T > &x, const Array< T > &y)
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)
#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)
N Dimensional Array with copy-on-write semantics.
void resize(const dim_vector &dv, const T &rfv)
Size of the specified dimension.
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.
Vector representing the dimensions (size) of an Array.
static 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)
octave_idx_type length(void) const
Array< octave_value > array_value(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,...)
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::octave_value(const Array< char > &chm, char type) return retval
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