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 ())
222 else if (args(q).type_id () == octave_uint32_matrix::static_type_id ()
223 || args(q).type_id () == octave_uint32_scalar::static_type_id ())
230 else if (args(q).type_id () == octave_uint16_matrix::static_type_id ()
231 || args(q).type_id () == octave_uint16_scalar::static_type_id ())
238 else if (args(q).type_id () == octave_uint8_matrix::static_type_id ()
239 || args(q).type_id () == octave_uint8_scalar::static_type_id ())
246 else if (args(q).type_id () == octave_int64_matrix::static_type_id ()
247 || args(q).type_id () == octave_int64_scalar::static_type_id ())
254 else if (args(q).type_id () == octave_int32_matrix::static_type_id ()
255 || args(q).type_id () == octave_int32_scalar::static_type_id ())
262 else if (args(q).type_id () == octave_int16_matrix::static_type_id ()
263 || args(q).type_id () == octave_int16_scalar::static_type_id ())
270 else if (args(q).type_id () == octave_int8_matrix::static_type_id ()
271 || args(q).type_id () == octave_int8_scalar::static_type_id ())
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 ())
292 else if (args(0).type_id () == octave_uint32_matrix::static_type_id ()
293 || args(0).type_id () == octave_uint32_scalar::static_type_id ())
300 else if (args(0).type_id () == octave_uint16_matrix::static_type_id ()
301 || args(0).type_id () == octave_uint16_scalar::static_type_id ())
308 else if (args(0).type_id () == octave_uint8_matrix::static_type_id ()
309 || args(0).type_id () == octave_uint8_scalar::static_type_id ())
316 else if (args(0).type_id () == octave_int64_matrix::static_type_id ()
317 || args(0).type_id () == octave_int64_scalar::static_type_id ())
324 else if (args(0).type_id () == octave_int32_matrix::static_type_id ()
325 || args(0).type_id () == octave_int32_scalar::static_type_id ())
332 else if (args(0).type_id () == octave_int16_matrix::static_type_id ()
333 || args(0).type_id () == octave_int16_scalar::static_type_id ())
340 else if (args(0).type_id () == octave_int8_matrix::static_type_id ()
341 || args(0).type_id () == octave_int8_scalar::static_type_id ())
349 error (
"%s: invalid operand type",
fname.c_str ());
352 error (
"%s: must have matching operand types",
fname.c_str ());
357 DEFUN (bitand, args, ,
366 return bitop (
"bitand", args);
373 DEFUN (bitor, args, ,
381 return bitop (
"bitor", args);
388 DEFUN (bitxor, args, ,
396 return bitop (
"bitxor", args);
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;
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 (); \ 565 int nargin = args.length ();
570 NDArray n = args(1).xarray_value (
"bitshift: K must be a scalar or array of integers");
578 if (args(2).
numel () > 1)
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 ());
658 DEFUN (flintmax, args, ,
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 ());
701 DEFUN (intmax, args, ,
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 ());
788 DEFUN (intmin, args, ,
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 ());
875 DEFUN (sizemax, args, ,
887 if (args.length () != 0)
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)
static std::string static_class_name(void)
OCTINTERP_API void print_usage(void)
octave_int< uint16_t > octave_uint16
T operator()(const T &op1, const T &op2) const
#define DEFUN(name, args_name, nargout_name, doc)
Macro to define a builtin function.
void error(const char *fmt,...)
T operator()(const T &op1, const T &op2) const
FloatNDArray float_array_value(bool frc_str_conv=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)
static std::string static_class_name(void)
Array< octave_value > array_value(void) const
octave_value bitop(const std::string &fname, const octave_value_list &args)
static std::string static_class_name(void)
std::string class_name(void) const
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)
#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.
charNDArray max(char d, const charNDArray &m)
boolNDArray bool_array_value(bool warn=false) const
T::size_type numel(const T &str)
OCTAVE_EXPORT octave_value_list isa nd deftypefn *return ovl(args(0).isinteger())
octave_int< int64_t > octave_int64
octave_idx_type length(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
NDArray array_value(bool frc_str_conv=false) const
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)
octave_int< int8_t > octave_int8