24 #if !defined (octave_oct_inttypes_h)
25 #define octave_oct_inttypes_h 1
36 #ifdef OCTAVE_INT_USE_LONG_DOUBLE
37 inline long double xround (
long double x) {
return roundl (x); }
38 inline long double xisnan (
long double x)
39 {
return xisnan (static_cast<double> (x)); }
49 template<
int qsize,
bool q
signed>
58 #define REGISTER_INT_TYPE(TYPE) \
60 class query_integer_type<sizeof (TYPE), std::numeric_limits<TYPE>::is_signed> \
63 static const bool registered = true; \
80 #define REGISTER_OCTAVE_CMP_OP(NM,OP) \
84 static const bool ltval = (0 OP 1); \
85 static const bool gtval = (1 OP 0); \
87 static bool op (T x, T y) { return x OP y; } \
92 #define REGISTER_OCTAVE_CONST_OP(NM,value) \
96 static const bool ltval = value; \
97 static const bool gtval = value; \
99 static bool op (T, T) { return value; } \
110 template <
class T1,
class T2>
114 static const bool pint = (
sizeof (T1) <
sizeof (
int)
115 &&
sizeof (T2) <
sizeof (
int));
116 static const bool t1sig = std::numeric_limits<T1>::is_signed;
117 static const bool t2sig = std::numeric_limits<T2>::is_signed;
119 (pint || (
sizeof (T2) >
sizeof (T1) &&
t2sig) || t1sig);
121 (pint ?
sizeof (
int) : (
sizeof (T2) >
sizeof (T1)
122 ?
sizeof (T2) :
sizeof (T1)));
129 template<
class xop,
int size>
135 static bool op (utype x, utype y)
136 {
return xop::op (x, y); }
137 static bool op (stype x, stype y)
138 {
return xop::op (x, y); }
139 static bool op (stype x, utype y)
140 {
return (x < 0) ? xop::ltval : xop::op (static_cast<utype> (x), y); }
141 static bool op (utype x, stype y)
142 {
return (y < 0) ? xop::gtval : xop::op (x, static_cast<utype> (y)); }
156 template<
class xop,
class T1,
class T2>
163 static_cast<PT2> (y));
169 template <
class xop,
class T>
172 {
return xop::op (static_cast<double> (x), y); }
174 template <
class xop,
class T>
177 {
return xop::op (x, static_cast<double> (y)); }
179 #ifdef OCTAVE_ENSURE_LONG_DOUBLE_OPERATIONS_ARE_NOT_TRUNCATED
180 #define DECLARE_EXTERNAL_LONG_DOUBLE_CMP_OPS(T) \
181 template <class xop> static OCTAVE_API bool \
182 external_mop (double, T); \
183 template <class xop> static OCTAVE_API bool \
184 external_mop (T, double)
186 DECLARE_EXTERNAL_LONG_DOUBLE_CMP_OPS (int64_t);
187 DECLARE_EXTERNAL_LONG_DOUBLE_CMP_OPS (uint64_t);
193 #ifdef OCTAVE_INT_USE_LONG_DOUBLE
194 #ifdef OCTAVE_ENSURE_LONG_DOUBLE_OPERATIONS_ARE_NOT_TRUNCATED
195 #define DEFINE_LONG_DOUBLE_CMP_OP(T) \
196 template <class xop> \
198 mop (double x, T y) \
200 return external_mop<xop> (x, y); \
202 template <class xop> \
204 mop (T x, double y) \
206 return external_mop<xop> (x, y); \
209 #define DEFINE_LONG_DOUBLE_CMP_OP(T) \
210 template <class xop> \
212 mop (double x, T y) \
214 return xop::op (static_cast<long double> (x), \
215 static_cast<long double> (y)); \
217 template <class xop> \
219 mop (T x, double y) \
221 return xop::op (static_cast<long double> (x), \
222 static_cast<long double> (y)); \
231 #define DEFINE_LONG_DOUBLE_CMP_OP(T) \
232 template <class xop> static OCTAVE_API bool \
233 emulate_mop (double, T); \
234 template <class xop> \
236 mop (double x, T y) \
238 return emulate_mop<xop> (x, y); \
240 template <class xop> static OCTAVE_API bool \
241 emulate_mop (T, double); \
242 template <class xop> \
244 mop (T x, double y) \
246 return emulate_mop<xop> (x, y); \
253 #undef DEFINE_LONG_DOUBLE_CMP_OP
271 static const bool t_is_signed = std::numeric_limits<T>::is_signed;
272 static const bool s_is_signed = std::numeric_limits<S>::is_signed;
273 static const int t_size =
sizeof (T);
274 static const int s_size =
sizeof (S);
276 static const bool omit_chk_min =
277 (! s_is_signed || (t_is_signed && t_size >= s_size));
278 static const bool omit_chk_max =
279 (t_size > s_size || (t_size == s_size
280 && (! t_is_signed || s_is_signed)));
290 if (chk_min::op (value, static_cast<S> (
min_val ())))
294 else if (chk_max::op (value, static_cast<S> (
max_val ())))
299 return static_cast<T
> (value);
311 if (orig_val % 2 && val / 2 ==
xround (val / 2))
313 val *= (
static_cast<S
> (1) - (std::numeric_limits<S>::epsilon () / 2));
330 return static_cast<T
> (0);
332 else if (value < thmin)
336 else if (value > thmax)
342 S rvalue =
xround (value);
343 return static_cast<T
> (rvalue);
353 template <
class T,
bool is_
signed>
368 signum (T x) {
return x ?
static_cast<T
> (1) : static_cast<T> (0); }
380 return static_cast<T
> (0);
417 * static_cast<mptype> (y));
429 if (w >= y-w) z += 1;
442 return y != 0 ? x % y : 0;
449 return y != 0 ? x % y :
x;
453 #ifdef OCTAVE_INT_USE_LONG_DOUBLE
457 #ifdef OCTAVE_ENSURE_LONG_DOUBLE_OPERATIONS_ARE_NOT_TRUNCATED
459 extern OCTAVE_API uint64_t
460 octave_external_uint64_uint64_mul (uint64_t, uint64_t);
470 long double p =
static_cast<long double> (
x) * static_cast<long double> (y);
475 retval =
static_cast<uint64_t
> (p);
484 #ifdef OCTAVE_ENSURE_LONG_DOUBLE_OPERATIONS_ARE_NOT_TRUNCATED
485 return octave_external_uint64_uint64_mul (x, y);
487 return mul_internal (x, y);
531 #ifdef HAVE_FAST_INT_OPS
532 return static_cast<UT
> (
x) >> std::numeric_limits<T>::digits;
534 return (x < 0) ? 1 : 0;
541 #ifdef HAVE_FAST_INT_OPS
545 T m = x >> std::numeric_limits<T>::digits;
564 y = (x < 0) ? -x : x;
573 return ((x > 0) ? 1 : 0) - __signbit (x);
590 #ifdef HAVE_FAST_INT_OPS
613 #ifdef HAVE_FAST_INT_OPS
617 T u =
static_cast<UT
> (
x) + static_cast<UT> (y);
655 #ifdef HAVE_FAST_INT_OPS
659 T u =
static_cast<UT
> (
x) - static_cast<UT> (y);
703 * static_cast<mptype> (y));
733 z -= 1 - (__signbit (x) << 1);
745 z += 1 - (__signbit (x) << 1);
754 return y != 0 ? x % y : 0;
764 return ((r < 0) != (y < 0)) ? r + y : r;
771 #ifdef OCTAVE_INT_USE_LONG_DOUBLE
775 #ifdef OCTAVE_ENSURE_LONG_DOUBLE_OPERATIONS_ARE_NOT_TRUNCATED
777 extern OCTAVE_API int64_t
778 octave_external_int64_int64_mul (int64_t, int64_t);
788 long double p =
static_cast<long double> (
x) * static_cast<long double> (y);
798 retval =
static_cast<int64_t
> (p);
807 #ifdef OCTAVE_ENSURE_LONG_DOUBLE_OPERATIONS_ARE_NOT_TRUNCATED
808 return octave_external_int64_int64_mul (x, y);
810 return mul_internal (x, y);
849 #ifdef OCTAVE_INT_USE_LONG_DOUBLE
870 T
value (
void)
const {
return ival; }
872 const unsigned char *
iptr (
void)
const
873 {
return reinterpret_cast<const unsigned char *
> (& ival); }
877 bool bool_value (
void)
const {
return static_cast<bool> (value ()); }
879 char char_value (
void)
const {
return static_cast<char> (value ()); }
881 double double_value (
void)
const {
return static_cast<double> (value ()); }
883 float float_value (
void)
const {
return static_cast<float> (value ()); }
885 operator T (
void)
const {
return value (); }
889 operator double (
void)
const {
return double_value (); }
891 operator float (
void)
const {
return float_value (); }
898 #define OCTAVE_INT_UN_OP(OPNAME,NAME) \
899 inline octave_int<T> \
901 { return octave_int_arith<T>::NAME (ival); }
907 #undef OCTAVE_INT_UN_OP
910 #define OCTAVE_INT_BIN_OP(OP, NAME, ARGT) \
911 inline octave_int<T> \
912 operator OP (const ARGT& y) const \
913 { return octave_int_arith<T>::NAME (ival, y); } \
914 inline octave_int<T>& \
915 operator OP##= (const ARGT& y) \
917 ival = octave_int_arith<T>::NAME (ival, y); \
929 #undef OCTAVE_INT_BIN_OP
934 static int nbits (
void) {
return std::numeric_limits<T>::digits; }
938 static const char *type_name ();
1004 #define OCTAVE_INT_CMP_OP(OP, NAME) \
1005 template<class T1, class T2> \
1007 operator OP (const octave_int<T1>& x, const octave_int<T2>& y) \
1008 { return octave_int_cmp_op::op<octave_int_cmp_op::NAME, T1, T2> \
1009 (x.value (), y.value ()); }
1018 #undef OCTAVE_INT_CMP_OP
1021 inline std::ostream&
1022 operator << (std::ostream& os, const octave_int<T>& ival)
1024 os << ival.value ();
1029 inline std::istream&
1045 inline std::ostream&
1046 operator << (std::ostream& os, const octave_int<int8_t>& ival)
1048 os << static_cast<int> (ival.value ());
1053 inline std::ostream&
1054 operator << (std::ostream& os, const octave_int<uint8_t>& ival)
1056 os << static_cast<unsigned int> (ival.value ());
1062 inline std::istream&
1067 ival =
static_cast<int8_t
> (tmp);
1072 inline std::istream&
1075 unsigned int tmp = 0;
1077 ival =
static_cast<uint8_t
> (tmp);
1084 #define OCTAVE_INT_BITCMP_OP(OP) \
1085 template <class T> \
1087 operator OP (const octave_int<T>& x, const octave_int<T>& y) \
1088 { return x.value () OP y.value (); }
1094 #undef OCTAVE_INT_BITCMP_OP
1103 return (a << n) & mask;
1105 return (a >> -n) & mask;
1120 #ifdef OCTAVE_ENSURE_LONG_DOUBLE_OPERATIONS_ARE_NOT_TRUNCATED
1122 #define DECLARE_EXTERNAL_LONG_DOUBLE_OP(T, OP) \
1123 extern OCTAVE_API T \
1124 external_double_ ## T ## _ ## OP (double x, T y); \
1125 extern OCTAVE_API T \
1126 external_ ## T ## _double_ ## OP (T x, double y)
1128 #define DECLARE_EXTERNAL_LONG_DOUBLE_OPS(T) \
1129 DECLARE_EXTERNAL_LONG_DOUBLE_OP (T, add); \
1130 DECLARE_EXTERNAL_LONG_DOUBLE_OP (T, sub); \
1131 DECLARE_EXTERNAL_LONG_DOUBLE_OP (T, mul); \
1132 DECLARE_EXTERNAL_LONG_DOUBLE_OP (T, div)
1134 DECLARE_EXTERNAL_LONG_DOUBLE_OPS (octave_int64);
1135 DECLARE_EXTERNAL_LONG_DOUBLE_OPS (octave_uint64);
1139 #define OCTAVE_INT_DOUBLE_BIN_OP0(OP) \
1140 template <class T> \
1141 inline octave_int<T> \
1142 operator OP (const octave_int<T>& x, const double& y) \
1143 { return octave_int<T> (static_cast<double> (x) OP y); } \
1144 template <class T> \
1145 inline octave_int<T> \
1146 operator OP (const double& x, const octave_int<T>& y) \
1147 { return octave_int<T> (x OP static_cast<double> (y)); }
1149 #ifdef OCTAVE_INT_USE_LONG_DOUBLE
1151 #ifdef OCTAVE_ENSURE_LONG_DOUBLE_OPERATIONS_ARE_NOT_TRUNCATED
1152 #define OCTAVE_INT_DOUBLE_BIN_OP(OP, NAME) \
1153 OCTAVE_INT_DOUBLE_BIN_OP0(OP) \
1155 inline octave_int64 \
1156 operator OP (const double& x, const octave_int64& y) \
1158 return external_double_octave_int64_ ## NAME (x, y); \
1161 inline octave_uint64 \
1162 operator OP (const double& x, const octave_uint64& y) \
1164 return external_double_octave_uint64_ ## NAME (x, y); \
1167 inline octave_int64 \
1168 operator OP (const octave_int64& x, const double& y) \
1170 return external_octave_int64_double_ ## NAME (x, y); \
1173 inline octave_uint64 \
1174 operator OP (const octave_uint64& x, const double& y) \
1176 return external_octave_uint64_double_ ## NAME (x, y); \
1179 #define OCTAVE_INT_DOUBLE_BIN_OP(OP, NAME) \
1180 OCTAVE_INT_DOUBLE_BIN_OP0(OP) \
1182 inline octave_int64 \
1183 operator OP (const double& x, const octave_int64& y) \
1185 return octave_int64 (x OP static_cast<long double> (y.value ())); \
1188 inline octave_uint64 \
1189 operator OP (const double& x, const octave_uint64& y) \
1191 return octave_uint64 (x OP static_cast<long double> (y.value ())); \
1194 inline octave_int64 \
1195 operator OP (const octave_int64& x, const double& y) \
1197 return octave_int64 (static_cast<long double> (x.value ()) OP y); \
1200 inline octave_uint64 \
1201 operator OP (const octave_uint64& x, const double& y) \
1203 return octave_uint64 (static_cast<long double> (x.value ()) OP y); \
1208 #define OCTAVE_INT_DOUBLE_BIN_OP(OP, NAME) \
1209 OCTAVE_INT_DOUBLE_BIN_OP0(OP) \
1211 OCTAVE_API octave_int64 \
1212 operator OP (const double&, const octave_int64&); \
1214 OCTAVE_API octave_uint64 \
1215 operator OP (const double&, const octave_uint64&); \
1217 OCTAVE_API octave_int64 \
1218 operator OP (const octave_int64&, const double&); \
1220 OCTAVE_API octave_uint64 \
1221 operator OP (const octave_uint64&, const double&);
1230 #undef OCTAVE_INT_DOUBLE_BIN_OP0
1231 #undef OCTAVE_INT_DOUBLE_BIN_OP
1232 #undef DECLARE_EXTERNAL_LONG_DOUBLE_OP
1233 #undef DECLARE_EXTERNAL_LONG_DOUBLE_OPS
1235 #define OCTAVE_INT_DOUBLE_CMP_OP(OP,NAME) \
1236 template <class T> \
1238 operator OP (const octave_int<T>& x, const double& y) \
1239 { return octave_int_cmp_op::mop<octave_int_cmp_op::NAME> (x.value (), y); } \
1240 template <class T> \
1242 operator OP (const double& x, const octave_int<T>& y) \
1243 { return octave_int_cmp_op::mop<octave_int_cmp_op::NAME> (x, y.value ()); }
1252 #undef OCTAVE_INT_DOUBLE_CMP_OP
1256 #define OCTAVE_INT_FLOAT_BIN_OP(OP) \
1257 template <class T> \
1258 inline octave_int<T> \
1259 operator OP (const octave_int<T>& x, float y) \
1260 { return x OP static_cast<double> (y); } \
1261 template <class T> \
1262 inline octave_int<T> \
1263 operator OP (float x, const octave_int<T>& y) \
1264 { return static_cast<double> (x) OP y; }
1271 #undef OCTAVE_INT_FLOAT_BIN_OP
1273 #define OCTAVE_INT_FLOAT_CMP_OP(OP) \
1274 template <class T> \
1276 operator OP (const octave_int<T>& x, const float& y) \
1277 { return x OP static_cast<double> (y); } \
1278 template <class T> \
1280 operator OP (const float& x, const octave_int<T>& y) \
1281 { return static_cast<double> (x) OP y; }
1290 #undef OCTAVE_INT_FLOAT_CMP_OP
1296 const T xv = x.
value ();
1297 const T yv = y.
value ();
1305 const T xv = x.
value ();
1306 const T yv = y.
value ();
octave_int< uint32_t > octave_uint32
bool bool_value(void) const
static const bool registered
#define OCTAVE_INT_CMP_OP(OP, NAME)
#define OCTAVE_INT_BITCMP_OP(OP)
#define OCTAVE_INT_BIN_OP(OP, NAME, ARGT)
OCTAVE_API octave_int< T > pow(const octave_int< T > &, const octave_int< T > &)
octave_int< T > xmax(const octave_int< T > &x, const octave_int< T > &y)
#define OCTAVE_INT_FLOAT_BIN_OP(OP)
static bool op(utype x, stype y)
query_integer_type< size, true >::type stype
static T mul_internal(T x, T y)
static T lshift(T x, int n)
octave_int(const octave_int< U > &i)
octave_int< T > mod(const octave_int< T > &x, const octave_int< T > &y)
double double_value(void) const
octave_int< int16_t > octave_int16
std::istream & operator>>(std::istream &is, octave_int< T > &ival)
char char_value(void) const
query_integer_type< sizeof(T), false >::type UT
query_integer_type< psize, psig >::type type
#define REGISTER_OCTAVE_CMP_OP(NM, OP)
F77_RET_T const double const double double * d
static T truncate_int(const S &value)
bool xisnan(const octave_int< T > &)
octave_int< int32_t > octave_int32
query_integer_type< size, false >::type utype
octave_int< uint16_t > octave_uint16
static T rshift(T x, int n)
void * mex_get_data(void) const
static S compute_threshold(S val, T orig_val)
static bool op(T1 x, T2 y)
static bool op(stype x, stype y)
std::complex< double > w(std::complex< double > z, double relerr=0)
#define OCTAVE_INT_DOUBLE_CMP_OP(OP, NAME)
octave_int< int64_t > octave_int64
OCTAVE_API octave_int< T > powf(const float &a, const octave_int< T > &b)
static octave_int< T > max(void)
static T convert_real(const S &value)
static T lshift(T x, int n)
#define OCTAVE_INT_UN_OP(OPNAME, NAME)
const unsigned char * iptr(void) const
#define OCTAVE_INT_DOUBLE_BIN_OP(OP, NAME)
octave_int< uint64_t > octave_uint64
#define DEFINE_LONG_DOUBLE_CMP_OP(T)
octave_int< T > xmin(const octave_int< T > &x, const octave_int< T > &y)
static bool op(utype x, utype y)
static bool mop(T x, double y)
charNDArray max(char d, const charNDArray &m)
#define REGISTER_OCTAVE_CONST_OP(NM, value)
#define REGISTER_INT_TYPE(TYPE)
static octave_int< T > min(void)
static bool op(stype x, utype y)
static const octave_int zero
octave_int< T > rem(const octave_int< T > &x, const octave_int< T > &y)
static T mul_internal(T x, T y)
octave_int< T > bitshift(const octave_int< T > &a, int n, const octave_int< T > &mask=std::numeric_limits< T >::max())
#define OCTAVE_INT_FLOAT_CMP_OP(OP)
static int byte_size(void)
octave_value operator!(const octave_value &a)
octave_int< T > operator+(const octave_int< T > &x, const double &y)
octave_int< uint8_t > octave_uint8
static T rshift(T x, int n)
octave_int< int8_t > octave_int8
octave_int(const octave_int< T > &i)
static bool mop(double x, T y)
uint64_t mul_internal(uint64_t x, uint64_t y)
F77_RET_T const double * x
charNDArray min(char d, const charNDArray &m)
float float_value(void) const