26#if defined (HAVE_CONFIG_H)
42#define DEFINE_OCTAVE_INT_TYPENAME(TYPE, TYPENAME) \
44 OCTAVE_API const char * \
45 octave_int<TYPE>::type_name (void) { return TYPENAME; }
62 static const S thmin = compute_threshold (
static_cast<S
> (min_val ()),
64 static const S thmax = compute_threshold (
static_cast<S
> (max_val ()),
67 return static_cast<T
> (0);
68 else if (value < thmin)
70 else if (value > thmax)
75 return static_cast<T
> (rvalue);
79#define INSTANTIATE_CONVERT_REAL_1(T, S) \
83 octave_int_base<T>::convert_real (const S&)
85#define INSTANTIATE_CONVERT_REAL(S) \
86 INSTANTIATE_CONVERT_REAL_1 (int8_t, S); \
87 INSTANTIATE_CONVERT_REAL_1 (uint8_t, S); \
88 INSTANTIATE_CONVERT_REAL_1 (int16_t, S); \
89 INSTANTIATE_CONVERT_REAL_1 (uint16_t, S); \
90 INSTANTIATE_CONVERT_REAL_1 (int32_t, S); \
91 INSTANTIATE_CONVERT_REAL_1 (uint32_t, S); \
92 INSTANTIATE_CONVERT_REAL_1 (int64_t, S); \
93 INSTANTIATE_CONVERT_REAL_1 (uint64_t, S)
97#if defined (OCTAVE_INT_USE_LONG_DOUBLE)
101#if defined (OCTAVE_INT_USE_LONG_DOUBLE)
103# if defined (OCTAVE_ENSURE_LONG_DOUBLE_OPERATIONS_ARE_NOT_TRUNCATED)
105# define DEFINE_OCTAVE_LONG_DOUBLE_CMP_OP_TEMPLATES(T) \
106 template <typename xop> \
108 octave_int_cmp_op::external_mop (double x, T y) \
110 unsigned int oldcw = octave_begin_long_double_rounding (); \
112 bool retval = xop::op (static_cast<long double> (x), \
113 static_cast<long double> (y)); \
115 octave_end_long_double_rounding (oldcw); \
120 template <typename xop> \
122 octave_int_cmp_op::external_mop (T x, double y) \
124 unsigned int oldcw = octave_begin_long_double_rounding (); \
126 bool retval = xop::op (static_cast<long double> (x), \
127 static_cast<long double> (y)); \
129 octave_end_long_double_rounding (oldcw); \
134DEFINE_OCTAVE_LONG_DOUBLE_CMP_OP_TEMPLATES (int64_t)
135DEFINE_OCTAVE_LONG_DOUBLE_CMP_OP_TEMPLATES (uint64_t)
137# define INSTANTIATE_LONG_DOUBLE_LONG_DOUBLE_CMP_OP(OP, T) \
138 template OCTAVE_API bool \
139 octave_int_cmp_op::external_mop<octave_int_cmp_op::OP> (double, T); \
141 template OCTAVE_API bool \
142 octave_int_cmp_op::external_mop<octave_int_cmp_op::OP> (T, double)
144# define INSTANTIATE_LONG_DOUBLE_LONG_DOUBLE_CMP_OPS(T) \
145 INSTANTIATE_LONG_DOUBLE_LONG_DOUBLE_CMP_OP (lt, T); \
146 INSTANTIATE_LONG_DOUBLE_LONG_DOUBLE_CMP_OP (le, T); \
147 INSTANTIATE_LONG_DOUBLE_LONG_DOUBLE_CMP_OP (gt, T); \
148 INSTANTIATE_LONG_DOUBLE_LONG_DOUBLE_CMP_OP (ge, T); \
149 INSTANTIATE_LONG_DOUBLE_LONG_DOUBLE_CMP_OP (eq, T); \
150 INSTANTIATE_LONG_DOUBLE_LONG_DOUBLE_CMP_OP (ne, T)
152INSTANTIATE_LONG_DOUBLE_LONG_DOUBLE_CMP_OPS (int64_t);
153INSTANTIATE_LONG_DOUBLE_LONG_DOUBLE_CMP_OPS (uint64_t);
156octave_external_uint64_uint64_mul (uint64_t
x, uint64_t y)
168octave_external_int64_int64_mul (int64_t
x, int64_t y)
187# define DEFINE_OCTAVE_LONG_DOUBLE_OP(T, OP, NAME) \
189 external_double_ ## T ## _ ## NAME (double x, T y) \
191 unsigned int oldcw = octave_begin_long_double_rounding (); \
193 T retval = T (x OP static_cast<long double> (y.value ())); \
195 octave_end_long_double_rounding (oldcw); \
201 external_ ## T ## _double_ ## NAME (T x, double y) \
203 unsigned int oldcw = octave_begin_long_double_rounding (); \
205 T retval = T (static_cast<long double> (x.value ()) OP y); \
207 octave_end_long_double_rounding (oldcw); \
212# define DEFINE_OCTAVE_LONG_DOUBLE_OPS(T) \
213 DEFINE_OCTAVE_LONG_DOUBLE_OP (T, +, add); \
214 DEFINE_OCTAVE_LONG_DOUBLE_OP (T, -, sub); \
215 DEFINE_OCTAVE_LONG_DOUBLE_OP (T, *, mul); \
216 DEFINE_OCTAVE_LONG_DOUBLE_OP (T, /, div)
227template <
typename xop>
234 static const double xxup
240 return xop::op (xx, y);
247 return xop::op (
x,
static_cast<uint64_t
> (xx));
251template <
typename xop>
259 static const double xxup
261 static const double xxlo
267 return xop::op (xx, y);
276 return xop::op (
x,
static_cast<int64_t
> (xx));
284template <
typename xop>
291#define DEFINE_REVERTED_OPERATOR(OP1, OP2) \
293 class rev_op<octave_int_cmp_op::OP1> \
296 typedef octave_int_cmp_op::OP2 op; \
304template <
typename xop>
309 return mop<rop> (y,
x);
312template <
typename xop>
317 return mop<rop> (y,
x);
327 uint64_t ux =
x >> 32;
328 uint64_t uy = y >> 32;
336 uint64_t ly =
static_cast<uint32_t
> (y);
337 uint64_t uxly = ux*ly;
341 uint64_t lx =
static_cast<uint32_t
> (
x);
342 uint64_t lxly = lx*ly;
343 res = add (uxly, lxly);
348 uint64_t lx =
static_cast<uint32_t
> (
x);
349 uint64_t uylx = uy*lx;
353 uint64_t ly =
static_cast<uint32_t
> (y);
354 uint64_t lylx = ly*lx;
355 res = add (uylx, lylx);
359 uint64_t lx =
static_cast<uint32_t
> (
x);
360 uint64_t ly =
static_cast<uint32_t
> (y);
383 bool positive = (
x < 0) == (y < 0);
386 uint64_t ux = usx >> 32;
387 uint64_t uy = usy >> 32;
395 uint64_t ly =
static_cast<uint32_t
> (usy);
396 uint64_t uxly = ux*ly;
400 uint64_t lx =
static_cast<uint32_t
> (usx);
401 uint64_t lxly = lx*ly;
409 uint64_t lx =
static_cast<uint32_t
> (usx);
410 uint64_t uylx = uy*lx;
414 uint64_t ly =
static_cast<uint32_t
> (usy);
415 uint64_t lylx = ly*lx;
422 uint64_t lx =
static_cast<uint32_t
> (usx);
423 uint64_t ly =
static_cast<uint32_t
> (usy);
429 if (res >
static_cast<uint64_t
> (max_val ()))
432 return static_cast<int64_t
> (res);
436 if (res >
static_cast<uint64_t
> (min_val ()))
439 return -
static_cast<int64_t
> (res);
443 return positive ? max_val () : min_val ();
480 return (
x + y2) + y2;
511 const double p2_64 =
std::pow (2.0, 64);
514 const uint64_t p2_64my = (~y.value ()) + 1;
558 uint64_t lx =
static_cast<uint32_t
> (
x);
559 uint64_t ux =
x >> 32;
560 uint64_t ly =
static_cast<uint32_t
> (y);
561 uint64_t uy = y >> 32;
562 uint64_t a = lx * ly;
564 uint64_t uxly = ux*ly;
565 uint64_t uylx = uy*lx;
566 a +=
static_cast<uint32_t
> (uxly); uxly >>= 32;
567 a +=
static_cast<uint32_t
> (uylx); uylx >>= 32;
569 uint64_t uxuy = ux * uy;
570 a += uxly; a += uylx; a += uxuy;
579 sign =
x < 0;
x = fabs (
x);
582 mtis =
static_cast<uint64_t
> (ldexp (
x, 52));
590 double x = ldexp (
static_cast<double> (mtis), exp);
591 return sign ? -
x :
x;
616 for (
short i = 0; i < 4; i++)
641 else if (fabs (y) == 0.5)
652 sign = (sign != (
x.value () < 0));
655 for (
short i = 0; i < 4; i++)
711#define INSTANTIATE_INT64_DOUBLE_CMP_OP0(OP, T1, T2) \
712 template OCTAVE_API bool \
713 octave_int_cmp_op::emulate_mop<octave_int_cmp_op::OP> (T1 x, T2 y)
715#define INSTANTIATE_INT64_DOUBLE_CMP_OP(OP) \
716 INSTANTIATE_INT64_DOUBLE_CMP_OP0 (OP, double, int64_t); \
717 INSTANTIATE_INT64_DOUBLE_CMP_OP0 (OP, double, uint64_t); \
718 INSTANTIATE_INT64_DOUBLE_CMP_OP0 (OP, int64_t, double); \
719 INSTANTIATE_INT64_DOUBLE_CMP_OP0 (OP, uint64_t, double)
739 if (b == zero || a == one)
744 retval = (b.
value () % 2) ? a : one;
760 retval = retval * a_val;
765 a_val = a_val * a_val;
781 return ((b >= 0 && b < std::numeric_limits<T>::digits
796 return ((b >= 0 && b < std::numeric_limits<T>::digits
800 static_cast<double> (b))));
814 return ((b >= 0 && b < std::numeric_limits<T>::digits
818 static_cast<double> (b))));
821#define INSTANTIATE_INTTYPE(T) \
822 template class octave_int<T>; \
824 template OCTAVE_API octave_int<T> \
825 pow (const octave_int<T>&, const octave_int<T>&); \
827 template OCTAVE_API octave_int<T> \
828 pow (const double&, const octave_int<T>&); \
830 template OCTAVE_API octave_int<T> \
831 pow (const octave_int<T>&, const double&); \
833 template OCTAVE_API octave_int<T> \
834 pow (const float&, const octave_int<T>&); \
836 template OCTAVE_API octave_int<T> \
837 pow (const octave_int<T>&, const float&); \
839 template OCTAVE_API octave_int<T> \
840 powf (const float&, const octave_int<T>&); \
842 template OCTAVE_API octave_int<T> \
843 powf (const octave_int<T>&, const float&); \
845 template OCTAVE_API octave_int<T> \
846 bitshift (const octave_int<T>&, int, const octave_int<T>&);
charNDArray max(char d, const charNDArray &m)
charNDArray min(char d, const charNDArray &m)
uint64_t mul_internal(uint64_t x, uint64_t y)
static OCTAVE_API bool emulate_mop(double, int64_t)
static octave_int< T > max(void)
bool bool_value(void) const
static const octave_int s_zero
static const octave_int s_one
double double_value(void) const
float float_value(void) const
unsigned int octave_begin_long_double_rounding(void)
void octave_end_long_double_rounding(unsigned int oldcw)
F77_RET_T const F77_DBLE * x
std::complex< double > w(std::complex< double > z, double relerr=0)
double frexp(double x, int *expptr)
octave_int< int64_t > octave_int64
octave_int< uint64_t > octave_uint64
static void umul128(uint64_t x, uint64_t y, uint32_t w[4])
#define INSTANTIATE_INTTYPE(T)
octave_int< T > pow(const octave_int< T > &a, const octave_int< T > &b)
OCTAVE_API octave_uint64 operator-(const octave_uint64 &x, const double &y)
OCTAVE_API octave_uint64 operator+(const octave_uint64 &x, const double &y)
static double dbleget(bool sign, uint32_t mtis, int exp)
OCTAVE_API octave_uint64 operator*(const octave_uint64 &x, const double &y)
#define INSTANTIATE_INT64_DOUBLE_CMP_OP(OP)
static void dblesplit(double x, bool &sign, uint64_t &mtis, int &exp)
OCTAVE_API octave_uint64 operator/(const double &x, const octave_uint64 &y)
#define DEFINE_OCTAVE_INT_TYPENAME(TYPE, TYPENAME)
#define DEFINE_REVERTED_OPERATOR(OP1, OP2)
#define INSTANTIATE_CONVERT_REAL(S)
octave_int< T > powf(const float &a, const octave_int< T > &b)