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); }
77 OCTAVE_END_NAMESPACE(std)
82 template <
typename OP,
typename T>
84 bitopxx (
const OP& op,
const std::string& fname,
87 int nelx =
x.numel ();
88 int nely = y.
numel ();
90 bool is_scalar_op = (nelx == 1 || nely == 1);
95 bool is_array_op = (dvx == dvy);
97 if (! is_array_op && ! is_scalar_op)
98 error (
"%s: size of X and Y must match, or one operand must be a scalar",
108 for (
int i = 0; i < nelx; i++)
110 for (
int k = 0; k < nely; k++)
111 result(i+k) = op (
x(i), y(k));
113 result(i) = op (
x(i), y(i));
122 template <
typename T>
126 if (fname ==
"bitand")
127 return bitopxx (std::bit_and<T>(), fname,
x, y);
128 if (fname ==
"bitor")
129 return bitopxx (std::bit_or<T>(), fname,
x, y);
132 return bitopxx (std::bit_xor<T>(), fname,
x, y);
170 bool arg0_is_int = bitop_arg_is_int (args(0));
171 bool arg1_is_int = bitop_arg_is_int (args(1));
173 bool arg0_is_bool = bitop_arg_is_bool (args(0));
174 bool arg1_is_bool = bitop_arg_is_bool (args(1));
176 bool arg0_is_float = bitop_arg_is_float (args(0));
177 bool arg1_is_float = bitop_arg_is_float (args(1));
179 if (! (arg0_is_int || arg1_is_int))
181 if (arg0_is_bool && arg1_is_bool)
188 else if (arg0_is_float && arg1_is_float)
195 else if (! (arg0_is_float || arg1_is_float))
204 int p = (arg0_is_float ? 1 : 0);
205 int q = (arg0_is_float ? 0 : 1);
215 int p = (arg0_is_int ? 1 : 0);
216 int q = (arg0_is_int ? 0 : 1);
228 else if (args(q).type_id () == octave_uint32_matrix::static_type_id ()
229 || args(q).type_id () == octave_uint32_scalar::static_type_id ())
236 else if (args(q).type_id () == octave_uint16_matrix::static_type_id ()
237 || args(q).type_id () == octave_uint16_scalar::static_type_id ())
244 else if (args(q).type_id () == octave_uint8_matrix::static_type_id ()
245 || args(q).type_id () == octave_uint8_scalar::static_type_id ())
252 else if (args(q).type_id () == octave_int64_matrix::static_type_id ()
253 || args(q).type_id () == octave_int64_scalar::static_type_id ())
260 else if (args(q).type_id () == octave_int32_matrix::static_type_id ()
261 || args(q).type_id () == octave_int32_scalar::static_type_id ())
268 else if (args(q).type_id () == octave_int16_matrix::static_type_id ()
269 || args(q).type_id () == octave_int16_scalar::static_type_id ())
276 else if (args(q).type_id () == octave_int8_matrix::static_type_id ()
277 || args(q).type_id () == octave_int8_scalar::static_type_id ())
285 error (
"%s: invalid operand type", fname.c_str ());
288 else if (args(0).class_name () == args(1).class_name ())
298 else if (args(0).type_id () == octave_uint32_matrix::static_type_id ()
299 || args(0).type_id () == octave_uint32_scalar::static_type_id ())
306 else if (args(0).type_id () == octave_uint16_matrix::static_type_id ()
307 || args(0).type_id () == octave_uint16_scalar::static_type_id ())
314 else if (args(0).type_id () == octave_uint8_matrix::static_type_id ()
315 || args(0).type_id () == octave_uint8_scalar::static_type_id ())
322 else if (args(0).type_id () == octave_int64_matrix::static_type_id ()
323 || args(0).type_id () == octave_int64_scalar::static_type_id ())
330 else if (args(0).type_id () == octave_int32_matrix::static_type_id ()
331 || args(0).type_id () == octave_int32_scalar::static_type_id ())
338 else if (args(0).type_id () == octave_int16_matrix::static_type_id ()
339 || args(0).type_id () == octave_int16_scalar::static_type_id ())
346 else if (args(0).type_id () == octave_int8_matrix::static_type_id ()
347 || args(0).type_id () == octave_int8_scalar::static_type_id ())
355 error (
"%s: invalid operand type", fname.c_str ());
358 error (
"%s: must have matching operand types", fname.c_str ());
363 DEFUN (bitand, args, ,
372 return bitop (
"bitand", args);
379 DEFUN (bitor, args, ,
387 return bitop (
"bitor", args);
394 DEFUN (bitxor, args, ,
402 return bitop (
"bitxor", args);
426 template <
typename T>
428 max_mantissa_value ()
430 return (
static_cast<int64_t
> (1) << std::numeric_limits<T>::digits) - 1;
441 return (
static_cast<int64_t
> (a) <<
n) & mask;
443 return (
static_cast<int64_t
> (a) >> -
n) & mask;
445 return static_cast<int64_t
> (a) & mask;
456 return (
static_cast<int64_t
> (a) <<
n) & mask;
458 return (
static_cast<int64_t
> (a) >> -
n) & mask;
460 return static_cast<int64_t
> (a) & mask;
467 #define DO_BITSHIFT(T) \
470 if (! n.all_integers (d1, d2)) \
471 error ("bitshift: K must be a scalar or array of integers"); \
473 int m_nel = m.numel (); \
474 int n_nel = n.numel (); \
476 bool is_scalar_op = (m_nel == 1 || n_nel == 1); \
478 dim_vector m_dv = m.dims (); \
479 dim_vector n_dv = n.dims (); \
481 bool is_array_op = (m_dv == n_dv); \
483 if (! is_array_op && ! is_scalar_op) \
484 error ("bitshift: size of A and N must match, or one operand must be a scalar"); \
486 T ## NDArray result; \
489 result.resize (m_dv); \
491 result.resize (n_dv); \
493 for (int i = 0; i < m_nel; i++) \
495 for (int k = 0; k < n_nel; k++) \
496 if (static_cast<int> (n(k)) >= bits_in_type) \
499 result(i+k) = bitshift (m(i), static_cast<int> (n(k)), mask); \
501 if (static_cast<int> (n(i)) >= bits_in_type) \
504 result(i) = bitshift (m(i), static_cast<int> (n(i)), mask); \
508 #define DO_UBITSHIFT(T, N) \
511 int bits_in_type = octave_ ## T :: nbits (); \
512 T ## NDArray m = m_arg.T ## _array_value (); \
513 octave_ ## T mask = octave_ ## T::max (); \
514 if ((N) < bits_in_type) \
515 mask = bitshift (mask, (N) - bits_in_type); \
522 #define DO_SBITSHIFT(T, N) \
525 int bits_in_type = octave_ ## T :: nbits (); \
526 T ## NDArray m = m_arg.T ## _array_value (); \
527 octave_ ## T mask = octave_ ## T::max (); \
528 if ((N) < bits_in_type) \
529 mask = bitshift (mask, (N) - bits_in_type); \
533 mask = mask | octave_ ## T :: min (); \
538 DEFUN (bitshift, args, ,
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 ());
659 DEFUN (flintmax, args, ,
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 ());
727 DEFUN (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 ());
841 DEFUN (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 ());
955 DEFUN (sizemax, args, ,
967 if (args.length () != 0)
979 OCTAVE_END_NAMESPACE(
octave)
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)
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)
charNDArray max(char d, const charNDArray &m)
charNDArray min(char d, const charNDArray &m)
void resize(const dim_vector &dv, const T &rfv)
Size of the specified dimension.
const dim_vector & dims() const
Return a const-reference so that dims ()(i) works efficiently.
octave_idx_type numel() const
Number of elements in the array.
Vector representing the dimensions (size) of an Array.
static octave_idx_type dim_max()
static std::string static_class_name()
static std::string static_class_name()
static std::string static_class_name()
static int static_type_id()
static int static_type_id()
Array< octave_value > array_value() const
octave_idx_type length() const
boolNDArray bool_array_value(bool warn=false) const
std::string class_name() const
NDArray array_value(bool frc_str_conv=false) const
FloatNDArray float_array_value(bool frc_str_conv=false) const
OCTAVE_BEGIN_NAMESPACE(octave) static octave_value daspk_fcn
#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
template octave_int< int8_t > bitshift(const octave_int< int8_t > &, int, const octave_int< int8_t > &)
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.