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)
208 return xop::op (x, static_cast<uint64_t> (xx));
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, uy = y >> 32;
291 uint64_t ly =
static_cast<uint32_t
> (y), uxly = ux*ly;
295 uint64_t lx =
static_cast<uint32_t
> (
x), lxly = lx*ly;
296 res = add (uxly, lxly);
301 uint64_t lx =
static_cast<uint32_t
> (
x), uylx = uy*lx;
305 uint64_t ly =
static_cast<uint32_t
> (y), lylx = ly*lx;
306 res = add (uylx, lylx);
310 uint64_t lx =
static_cast<uint32_t
> (
x);
311 uint64_t ly =
static_cast<uint32_t
> (y);
334 bool positive = (x < 0) == (y < 0);
337 uint64_t ux = usx >> 32, uy = usy >> 32;
345 uint64_t ly =
static_cast<uint32_t
> (usy), uxly = ux*ly;
349 uint64_t lx =
static_cast<uint32_t
> (usx), lxly = lx*ly;
357 uint64_t lx =
static_cast<uint32_t
> (usx), uylx = uy*lx;
361 uint64_t ly =
static_cast<uint32_t
> (usy), lylx = ly*lx;
368 uint64_t lx =
static_cast<uint32_t
> (usx);
369 uint64_t ly =
static_cast<uint32_t
> (usy);
375 if (res > static_cast<uint64_t> (max_val ()))
380 return static_cast<int64_t
> (res);
384 if (res > static_cast<uint64_t> (-min_val ()))
389 return -
static_cast<int64_t
> (res);
394 return positive ? max_val () : min_val ();
398 #define INT_DOUBLE_BINOP_DECL(OP,SUFFIX) \
400 OCTAVE_API octave_ ## SUFFIX \
401 operator OP (const octave_ ## SUFFIX & x, const double& y)
403 #define DOUBLE_INT_BINOP_DECL(OP,SUFFIX) \
405 OCTAVE_API octave_ ## SUFFIX \
406 operator OP (const double& x, const octave_ ## SUFFIX & y)
431 return (
x + y2) + y2;
454 const double p2_64 =
std::pow (2.0, 64);
457 const uint64_t p2_64my = (~y.value ()) + 1;
499 uint64_t lx =
static_cast<uint32_t
> (
x), ux = x >> 32;
500 uint64_t ly =
static_cast<uint32_t
> (y), uy = y >> 32;
501 uint64_t a = lx * ly;
503 uint64_t uxly = ux*ly, uylx = uy*lx;
504 a +=
static_cast<uint32_t
> (uxly); uxly >>= 32;
505 a +=
static_cast<uint32_t
> (uylx); uylx >>= 32;
507 uint64_t uxuy = ux * uy;
508 a += uxly; a += uylx; a += uxuy;
517 sign = x < 0; x = fabs (x);
518 x = gnulib::frexp (x, &exp);
520 mtis =
static_cast<uint64_t
> (ldexp (x, 52));
528 double x = ldexp (static_cast<double> (mtis), exp);
529 return sign ? -x :
x;
555 for (
short i = 0; i < 4; i++)
573 else if (fabs (y) == 0.5)
588 sign = (sign != (
x.value () < 0));
591 for (
short i = 0; i < 4; i++)
633 #define INSTANTIATE_INT64_DOUBLE_CMP_OP0(OP,T1,T2) \
634 template OCTAVE_API bool \
635 octave_int_cmp_op::emulate_mop<octave_int_cmp_op::OP> (T1 x, T2 y)
637 #define INSTANTIATE_INT64_DOUBLE_CMP_OP(OP) \
638 INSTANTIATE_INT64_DOUBLE_CMP_OP0(OP, double, int64_t); \
639 INSTANTIATE_INT64_DOUBLE_CMP_OP0(OP, double, uint64_t); \
640 INSTANTIATE_INT64_DOUBLE_CMP_OP0(OP, int64_t, double); \
641 INSTANTIATE_INT64_DOUBLE_CMP_OP0(OP, uint64_t, double)
668 if (b == zero || a == one)
673 retval = (b.
value () % 2) ? a : one;
689 retval = retval * a_val;
694 a_val = a_val * a_val;
710 return ((b >= 0 && b < std::numeric_limits<T>::digits && b ==
xround (b))
724 return ((b >= 0 && b < std::numeric_limits<T>::digits && b ==
xround (b))
741 return ((b >= 0 && b < std::numeric_limits<T>::digits && b ==
xround (b))
746 #define INSTANTIATE_INTTYPE(T) \
747 template class OCTAVE_API octave_int<T>; \
748 template OCTAVE_API octave_int<T> pow (const octave_int<T>&, const octave_int<T>&); \
749 template OCTAVE_API octave_int<T> pow (const double&, const octave_int<T>&); \
750 template OCTAVE_API octave_int<T> pow (const octave_int<T>&, const double&); \
751 template OCTAVE_API octave_int<T> pow (const float&, const octave_int<T>&); \
752 template OCTAVE_API octave_int<T> pow (const octave_int<T>&, const float&); \
753 template OCTAVE_API octave_int<T> powf (const float&, const octave_int<T>&); \
754 template OCTAVE_API octave_int<T> powf (const octave_int<T>&, const float&); \
755 template OCTAVE_API octave_int<T> \
756 bitshift (const octave_int<T>&, int, const octave_int<T>&); \