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 () { 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); \
134 DEFINE_OCTAVE_LONG_DOUBLE_CMP_OP_TEMPLATES (int64_t)
135 DEFINE_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)
152 INSTANTIATE_LONG_DOUBLE_LONG_DOUBLE_CMP_OPS (int64_t);
153 INSTANTIATE_LONG_DOUBLE_LONG_DOUBLE_CMP_OPS (uint64_t);
156 octave_external_uint64_uint64_mul (uint64_t
x, uint64_t y)
168 octave_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)
227 template <
typename xop>
234 static const double xxup
240 return xop::op (xx, y);
247 return xop::op (
x,
static_cast<uint64_t
> (xx));
251 template <
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));
284 template <
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; \
304 template <
typename xop>
308 typedef typename rev_op<xop>::op rop;
309 return mop<rop> (y,
x);
312 template <
typename xop>
316 typedef typename rev_op<xop>::op rop;
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);
384 return y == 0 ? 0 : (y < 0 ? max_val () : min_val ());
387 return x == 0 ? 0 : (
x < 0 ? max_val () : min_val ());
391 bool positive = (
x < 0) == (y < 0);
394 uint64_t ux = usx >> 32;
395 uint64_t uy = usy >> 32;
403 uint64_t ly =
static_cast<uint32_t
> (usy);
404 uint64_t uxly = ux*ly;
408 uint64_t lx =
static_cast<uint32_t
> (usx);
409 uint64_t lxly = lx*ly;
417 uint64_t lx =
static_cast<uint32_t
> (usx);
418 uint64_t uylx = uy*lx;
422 uint64_t ly =
static_cast<uint32_t
> (usy);
423 uint64_t lylx = ly*lx;
430 uint64_t lx =
static_cast<uint32_t
> (usx);
431 uint64_t ly =
static_cast<uint32_t
> (usy);
437 if (res >
static_cast<uint64_t
> (max_val ()))
440 return static_cast<int64_t
> (res);
444 if (res >
static_cast<uint64_t
> (min_val ()))
447 return -
static_cast<int64_t
> (res);
451 return positive ? max_val () : min_val ();
488 return (
x + y2) + y2;
519 const double p2_64 =
std::pow (2.0, 64);
522 const uint64_t p2_64my = (~y.
value ()) + 1;
564 umul128 (uint64_t
x, uint64_t y, uint32_t
w[4])
566 uint64_t lx =
static_cast<uint32_t
> (
x);
567 uint64_t ux =
x >> 32;
568 uint64_t ly =
static_cast<uint32_t
> (y);
569 uint64_t uy = y >> 32;
570 uint64_t a = lx * ly;
572 uint64_t uxly = ux*ly;
573 uint64_t uylx = uy*lx;
574 a +=
static_cast<uint32_t
> (uxly); uxly >>= 32;
575 a +=
static_cast<uint32_t
> (uylx); uylx >>= 32;
577 uint64_t uxuy = ux * uy;
578 a += uxly; a += uylx; a += uxuy;
585 dblesplit (
double x,
bool& sign, uint64_t& mtis,
int& exp)
587 sign =
x < 0;
x = fabs (
x);
590 mtis =
static_cast<uint64_t
> (ldexp (
x, 52));
596 dbleget (
bool sign, uint32_t mtis,
int exp)
598 double x = ldexp (
static_cast<double> (mtis), exp);
599 return sign ? -
x :
x;
620 dblesplit (y, sign, my, e);
622 umul128 (
x.value (), my,
w);
624 for (
short i = 0; i < 4; i++)
649 else if (fabs (y) == 0.5)
658 dblesplit (y, sign, my, e);
660 sign = (sign != (
x.value () < 0));
663 for (
short i = 0; i < 4; i++)
719 #define INSTANTIATE_INT64_DOUBLE_CMP_OP0(OP, T1, T2) \
720 template OCTAVE_API bool \
721 octave_int_cmp_op::emulate_mop<octave_int_cmp_op::OP> (T1 x, T2 y)
723 #define INSTANTIATE_INT64_DOUBLE_CMP_OP(OP) \
724 INSTANTIATE_INT64_DOUBLE_CMP_OP0 (OP, double, int64_t); \
725 INSTANTIATE_INT64_DOUBLE_CMP_OP0 (OP, double, uint64_t); \
726 INSTANTIATE_INT64_DOUBLE_CMP_OP0 (OP, int64_t, double); \
727 INSTANTIATE_INT64_DOUBLE_CMP_OP0 (OP, uint64_t, double)
738 template <
typename T>
747 if (b == zero || a == one)
752 retval = (b.
value () % 2) ? a : one;
768 retval = retval * a_val;
773 a_val = a_val * a_val;
780 template <
typename T>
785 template <
typename T>
789 return ((b >= 0 && b < std::numeric_limits<T>::digits
795 template <
typename T>
800 template <
typename T>
804 return ((b >= 0 && b < std::numeric_limits<T>::digits
808 static_cast<double> (b))));
813 template <
typename T>
818 template <
typename T>
822 return ((b >= 0 && b < std::numeric_limits<T>::digits
826 static_cast<double> (b))));
829 #define INSTANTIATE_INTTYPE(T) \
830 template class OCTAVE_CLASS_TEMPLATE_INSTANTIATION_API octave_int<T>; \
832 template OCTAVE_API octave_int<T> \
833 pow (const octave_int<T>&, const octave_int<T>&); \
835 template OCTAVE_API octave_int<T> \
836 pow (const double&, const octave_int<T>&); \
838 template OCTAVE_API octave_int<T> \
839 pow (const octave_int<T>&, const double&); \
841 template OCTAVE_API octave_int<T> \
842 pow (const float&, const octave_int<T>&); \
844 template OCTAVE_API octave_int<T> \
845 pow (const octave_int<T>&, const float&); \
847 template OCTAVE_API octave_int<T> \
848 powf (const float&, const octave_int<T>&); \
850 template OCTAVE_API octave_int<T> \
851 powf (const octave_int<T>&, const float&); \
853 template OCTAVE_API octave_int<T> \
854 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 bool emulate_mop(double, int64_t)
double double_value() const
static octave_int< T > max()
static const octave_int s_zero
static const octave_int s_one
float float_value() const
unsigned int octave_begin_long_double_rounding(void)
void octave_end_long_double_rounding(unsigned int oldcw)
double frexp(double x, int *expptr)
F77_RET_T const F77_DBLE * x
std::complex< double > w(std::complex< double > z, double relerr=0)
octave_int< int64_t > octave_int64
octave_int< uint64_t > octave_uint64
octave_uint64 operator*(const octave_uint64 &x, const double &y)
#define INSTANTIATE_INTTYPE(T)
octave_uint64 operator/(const double &x, const octave_uint64 &y)
#define INSTANTIATE_INT64_DOUBLE_CMP_OP(OP)
octave_uint64 operator+(const octave_uint64 &x, const double &y)
octave_uint64 operator-(const octave_uint64 &x, const double &y)
octave_int< T > powf(const float &a, const octave_int< T > &b)
#define DEFINE_OCTAVE_INT_TYPENAME(TYPE, TYPENAME)
#define DEFINE_REVERTED_OPERATOR(OP1, OP2)
#define INSTANTIATE_CONVERT_REAL(S)
octave_int< T > pow(const octave_int< T > &a, const octave_int< T > &b)