41 #define DECLARE_OCTAVE_INT_TYPENAME(TYPE, TYPENAME) \
43 OCTAVE_API const char * \
44 octave_int<TYPE>::type_name () { return TYPENAME; }
55 #ifdef OCTAVE_INT_USE_LONG_DOUBLE
57 #ifdef OCTAVE_ENSURE_LONG_DOUBLE_OPERATIONS_ARE_NOT_TRUNCATED
59 #define DEFINE_OCTAVE_LONG_DOUBLE_CMP_OP_TEMPLATES(T) \
60 template <class xop> \
62 octave_int_cmp_op::external_mop (double x, T y) \
64 DECL_LONG_DOUBLE_ROUNDING \
66 BEGIN_LONG_DOUBLE_ROUNDING (); \
68 bool retval = xop::op (static_cast<long double> (x), \
69 static_cast<long double> (y)); \
71 END_LONG_DOUBLE_ROUNDING (); \
76 template <class xop> \
78 octave_int_cmp_op::external_mop (T x, double y) \
80 DECL_LONG_DOUBLE_ROUNDING \
82 BEGIN_LONG_DOUBLE_ROUNDING (); \
84 bool retval = xop::op (static_cast<long double> (x), \
85 static_cast<long double> (y)); \
87 END_LONG_DOUBLE_ROUNDING (); \
92 DEFINE_OCTAVE_LONG_DOUBLE_CMP_OP_TEMPLATES (int64_t)
93 DEFINE_OCTAVE_LONG_DOUBLE_CMP_OP_TEMPLATES (uint64_t)
95 #define INSTANTIATE_LONG_DOUBLE_LONG_DOUBLE_CMP_OP(OP, T) \
96 template OCTAVE_API bool \
97 octave_int_cmp_op::external_mop<octave_int_cmp_op::OP> (double, T); \
98 template OCTAVE_API bool \
99 octave_int_cmp_op::external_mop<octave_int_cmp_op::OP> (T, double)
101 #define INSTANTIATE_LONG_DOUBLE_LONG_DOUBLE_CMP_OPS(T) \
102 INSTANTIATE_LONG_DOUBLE_LONG_DOUBLE_CMP_OP (lt, T); \
103 INSTANTIATE_LONG_DOUBLE_LONG_DOUBLE_CMP_OP (le, T); \
104 INSTANTIATE_LONG_DOUBLE_LONG_DOUBLE_CMP_OP (gt, T); \
105 INSTANTIATE_LONG_DOUBLE_LONG_DOUBLE_CMP_OP (ge, T); \
106 INSTANTIATE_LONG_DOUBLE_LONG_DOUBLE_CMP_OP (eq, T); \
107 INSTANTIATE_LONG_DOUBLE_LONG_DOUBLE_CMP_OP (ne, T)
109 INSTANTIATE_LONG_DOUBLE_LONG_DOUBLE_CMP_OPS (int64_t);
110 INSTANTIATE_LONG_DOUBLE_LONG_DOUBLE_CMP_OPS (uint64_t);
113 octave_external_uint64_uint64_mul (uint64_t
x, uint64_t y)
115 DECL_LONG_DOUBLE_ROUNDING
117 BEGIN_LONG_DOUBLE_ROUNDING ();
121 END_LONG_DOUBLE_ROUNDING ();
127 octave_external_int64_int64_mul (int64_t
x, int64_t y)
129 DECL_LONG_DOUBLE_ROUNDING
131 BEGIN_LONG_DOUBLE_ROUNDING ();
135 END_LONG_DOUBLE_ROUNDING ();
148 #define OCTAVE_LONG_DOUBLE_OP(T, OP, NAME) \
150 external_double_ ## T ## _ ## NAME (double x, T y) \
152 DECL_LONG_DOUBLE_ROUNDING \
154 BEGIN_LONG_DOUBLE_ROUNDING (); \
156 T retval = T (x OP static_cast<long double> (y.value ())); \
158 END_LONG_DOUBLE_ROUNDING (); \
164 external_ ## T ## _double_ ## NAME (T x, double y) \
166 DECL_LONG_DOUBLE_ROUNDING \
168 BEGIN_LONG_DOUBLE_ROUNDING (); \
170 T retval = T (static_cast<long double> (x.value ()) OP y); \
172 END_LONG_DOUBLE_ROUNDING (); \
177 #define OCTAVE_LONG_DOUBLE_OPS(T) \
178 OCTAVE_LONG_DOUBLE_OP (T, +, add); \
179 OCTAVE_LONG_DOUBLE_OP (T, -, sub); \
180 OCTAVE_LONG_DOUBLE_OP (T, *, mul); \
181 OCTAVE_LONG_DOUBLE_OP (T, /, div)
201 return xop::op (xx, y);
208 return xop::op (x, static_cast<uint64_t> (xx));
222 return xop::op (xx, y);
231 return xop::op (x, static_cast<int64_t> (xx));
246 #define DEFINE_REVERTED_OPERATOR(OP1,OP2) \
248 class rev_op<octave_int_cmp_op::OP1> \
251 typedef octave_int_cmp_op::OP2 op; \
264 return mop<rop> (y,
x);
272 return mop<rop> (y,
x);
283 uint64_t ux = x >> 32;
284 uint64_t uy = y >> 32;
292 uint64_t ly =
static_cast<uint32_t
> (y);
293 uint64_t uxly = ux*ly;
297 uint64_t lx =
static_cast<uint32_t
> (
x);
298 uint64_t lxly = lx*ly;
299 res = add (uxly, lxly);
304 uint64_t lx =
static_cast<uint32_t
> (
x);
305 uint64_t uylx = uy*lx;
309 uint64_t ly =
static_cast<uint32_t
> (y);
310 uint64_t lylx = ly*lx;
311 res = add (uylx, lylx);
315 uint64_t lx =
static_cast<uint32_t
> (
x);
316 uint64_t ly =
static_cast<uint32_t
> (y);
340 bool positive = (x < 0) == (y < 0);
343 uint64_t ux = usx >> 32;
344 uint64_t uy = usy >> 32;
352 uint64_t ly =
static_cast<uint32_t
> (usy);
353 uint64_t uxly = ux*ly;
357 uint64_t lx =
static_cast<uint32_t
> (usx);
358 uint64_t lxly = lx*ly;
366 uint64_t lx =
static_cast<uint32_t
> (usx);
367 uint64_t uylx = uy*lx;
371 uint64_t ly =
static_cast<uint32_t
> (usy);
372 uint64_t lylx = ly*lx;
379 uint64_t lx =
static_cast<uint32_t
> (usx);
380 uint64_t ly =
static_cast<uint32_t
> (usy);
386 if (res > static_cast<uint64_t> (max_val ()))
391 return static_cast<int64_t
> (res);
395 if (res > static_cast<uint64_t> (-min_val ()))
400 return -
static_cast<int64_t
> (res);
405 return positive ? max_val () : min_val ();
409 #define INT_DOUBLE_BINOP_DECL(OP,SUFFIX) \
411 OCTAVE_API octave_ ## SUFFIX \
412 operator OP (const octave_ ## SUFFIX & x, const double& y)
414 #define DOUBLE_INT_BINOP_DECL(OP,SUFFIX) \
416 OCTAVE_API octave_ ## SUFFIX \
417 operator OP (const double& x, const octave_ ## SUFFIX & y)
441 octave_int64 y2 (y / 2);
442 return (
x + y2) + y2;
465 const double p2_64 =
std::pow (2.0, 64);
468 const uint64_t p2_64my = (~y.value ()) + 1;
510 uint64_t lx =
static_cast<uint32_t
> (
x);
511 uint64_t ux = x >> 32;
512 uint64_t ly =
static_cast<uint32_t
> (y);
513 uint64_t uy = y >> 32;
514 uint64_t a = lx * ly;
516 uint64_t uxly = ux*ly;
517 uint64_t uylx = uy*lx;
518 a +=
static_cast<uint32_t
> (uxly); uxly >>= 32;
519 a +=
static_cast<uint32_t
> (uylx); uylx >>= 32;
521 uint64_t uxuy = ux * uy;
522 a += uxly; a += uylx; a += uxuy;
531 sign = x < 0; x = fabs (x);
532 x = gnulib::frexp (x, &exp);
534 mtis =
static_cast<uint64_t
> (ldexp (x, 52));
542 double x = ldexp (static_cast<double> (mtis), exp);
543 return sign ? -x :
x;
569 for (
short i = 0; i < 4; i++)
587 else if (fabs (y) == 0.5)
602 sign = (sign != (
x.value () < 0));
605 for (
short i = 0; i < 4; i++)
647 #define INSTANTIATE_INT64_DOUBLE_CMP_OP0(OP,T1,T2) \
648 template OCTAVE_API bool \
649 octave_int_cmp_op::emulate_mop<octave_int_cmp_op::OP> (T1 x, T2 y)
651 #define INSTANTIATE_INT64_DOUBLE_CMP_OP(OP) \
652 INSTANTIATE_INT64_DOUBLE_CMP_OP0(OP, double, int64_t); \
653 INSTANTIATE_INT64_DOUBLE_CMP_OP0(OP, double, uint64_t); \
654 INSTANTIATE_INT64_DOUBLE_CMP_OP0(OP, int64_t, double); \
655 INSTANTIATE_INT64_DOUBLE_CMP_OP0(OP, uint64_t, double)
682 if (b == zero || a == one)
687 retval = (b.
value () % 2) ? a : one;
703 retval = retval * a_val;
708 a_val = a_val * a_val;
724 return ((b >= 0 && b < std::numeric_limits<T>::digits && b ==
xround (b))
738 return ((b >= 0 && b < std::numeric_limits<T>::digits && b ==
xround (b))
755 return ((b >= 0 && b < std::numeric_limits<T>::digits && b ==
xround (b))
760 #define INSTANTIATE_INTTYPE(T) \
761 template class OCTAVE_API octave_int<T>; \
762 template OCTAVE_API octave_int<T> pow (const octave_int<T>&, const octave_int<T>&); \
763 template OCTAVE_API octave_int<T> pow (const double&, const octave_int<T>&); \
764 template OCTAVE_API octave_int<T> pow (const octave_int<T>&, const double&); \
765 template OCTAVE_API octave_int<T> pow (const float&, const octave_int<T>&); \
766 template OCTAVE_API octave_int<T> pow (const octave_int<T>&, const float&); \
767 template OCTAVE_API octave_int<T> powf (const float&, const octave_int<T>&); \
768 template OCTAVE_API octave_int<T> powf (const octave_int<T>&, const float&); \
769 template OCTAVE_API octave_int<T> \
770 bitshift (const octave_int<T>&, int, const octave_int<T>&);
static void umul128(uint64_t x, uint64_t y, uint32_t w[4])
double double_value(void) const
#define DOUBLE_INT_BINOP_DECL(OP, SUFFIX)
#define INT_DOUBLE_BINOP_DECL(OP, SUFFIX)
static const octave_int one
#define INSTANTIATE_INT64_DOUBLE_CMP_OP(OP)
octave_int< T > powf(const float &a, const octave_int< T > &b)
std::complex< double > w(std::complex< double > z, double relerr=0)
octave_int< int64_t > octave_int64
octave_int< T > pow(const octave_int< T > &a, const octave_int< T > &b)
static octave_int< T > max(void)
static OCTAVE_API bool emulate_mop(double, int64_t)
octave_int< uint64_t > octave_uint64
#define DEFINE_REVERTED_OPERATOR(OP1, OP2)
charNDArray max(char d, const charNDArray &m)
static const octave_int zero
static double dbleget(bool sign, uint32_t mtis, int exp)
#define INSTANTIATE_INTTYPE(T)
static void dblesplit(double x, bool &sign, uint64_t &mtis, int &exp)
uint64_t mul_internal(uint64_t x, uint64_t y)
#define DECLARE_OCTAVE_INT_TYPENAME(TYPE, TYPENAME)
F77_RET_T const double * x
charNDArray min(char d, const charNDArray &m)
float float_value(void) const