23 #ifndef PLLL_INCLUDE_GUARD__ARITHMETIC_GMP_CONVERSIONS_HPP
24 #define PLLL_INCLUDE_GUARD__ARITHMETIC_GMP_CONVERSIONS_HPP
37 namespace implementation
41 template<
class Data,
template<
typename,
typename>
class Op,
class Dest>
46 typedef void RetVal_Frac;
47 typedef void RetVal_Floor;
48 typedef void RetVal_Ceil;
49 typedef void RetVal_Round;
50 typedef void RetVal_Round2;
67 typedef void RetVal_Frac;
68 typedef void RetVal_Floor;
69 typedef void RetVal_Ceil;
70 typedef void RetVal_Round;
71 typedef void RetVal_Round2;
75 mpz_set_si(d.d_value, v);
88 typedef void RetVal_Frac;
89 typedef void RetVal_Floor;
90 typedef void RetVal_Ceil;
91 typedef void RetVal_Round;
92 typedef void RetVal_Round2;
96 mpz_set_ui(d.d_value, v);
109 typedef void RetVal_Frac;
110 typedef void RetVal_Floor;
111 typedef void RetVal_Ceil;
112 typedef void RetVal_Round;
113 typedef void RetVal_Round2;
117 mpz_set_si(d.d_value, v);
130 typedef void RetVal_Frac;
131 typedef void RetVal_Floor;
132 typedef void RetVal_Ceil;
133 typedef void RetVal_Round;
134 typedef void RetVal_Round2;
138 mpz_set_ui(d.d_value, v);
151 typedef void RetVal_Frac;
152 typedef void RetVal_Floor;
153 typedef void RetVal_Ceil;
154 typedef void RetVal_Round;
155 typedef void RetVal_Round2;
159 Integer::mpz_set_ll(d.d_value, v);
172 typedef void RetVal_Frac;
180 mpz_set_d(d.d_value, v);
190 mpz_set_d(d.d_value, std::floor(v));
195 return RetVal(std::floor(v), c);
200 mpz_set_d(d.d_value, rintf(v));
205 return RetVal(rintf(v), c);
212 mpz_set_d(d.d_value, rv);
224 mpz_set_d(d.d_value, std::ceil(v));
229 return RetVal(std::ceil(v), c);
237 typedef void RetVal_Frac;
245 mpz_set_d(d.d_value, v);
255 mpz_set_d(d.d_value, std::floor(v));
260 return RetVal(std::floor(v), c);
265 mpz_set_d(d.d_value, rint(v));
270 return RetVal(rint(v), c);
277 mpz_set_d(d.d_value, rv);
289 mpz_set_d(d.d_value, std::ceil(v));
302 typedef void RetVal_Frac;
310 Integer::mpz_set_ld(d.d_value, v);
320 Integer::mpz_set_ld(d.d_value, std::floor(v));
330 Integer::mpz_set_ld(d.d_value, rintl(v));
335 return RetVal(rintl(v), c);
340 long double rv = rintl(v);
342 Integer::mpz_set_ld(d.d_value, rv);
347 long double rv = rintl(v);
354 Integer::mpz_set_ld(d.d_value, std::ceil(v));
359 return RetVal(std::ceil(v), c);
366 static int toInt(
const Integer & v)
368 return mpz_get_si(v.d_value);
371 static unsigned int toUInt(
const Integer & v)
373 return mpz_get_ui(v.d_value);
376 static long toLong(
const Integer & v)
378 return mpz_get_si(v.d_value);
381 static unsigned long toULong(
const Integer & v)
383 return mpz_get_ui(v.d_value);
386 static long long toLongLong(
const Integer & v)
388 return arithmetic::Integer::mpz_get_ll(v.d_value);
391 static float toFloat(
const Integer & v)
393 return mpz_get_d(v.d_value);
396 static double toDouble(
const Integer & v)
398 return mpz_get_d(v.d_value);
401 static long double toLongDouble(
const Integer & v)
403 return arithmetic::Integer::mpz_get_ld(v.d_value);
407 template<
class Data,
template<
typename,
typename>
class Op>
class nativeconversion_impl<expressions::Expression<IntegerContext, Data, Op> >
458 typedef void RetVal_Floor;
459 typedef void RetVal_Ceil;
460 typedef void RetVal_Round;
461 typedef void RetVal_Round2;
465 mpfr_set_si(d.d_value, v, MPFR_RNDN);
473 static void convert_frac(
Real & d,
signed int v1,
signed int v2,
const RealContext & c)
475 mpfr_set_si(d.d_value, v1, MPFR_RNDN);
476 Real t((
signed long)v2, c);
482 Real t1((
signed long)v1, c), t2((
signed long)v2, c);
493 typedef void RetVal_Floor;
494 typedef void RetVal_Ceil;
495 typedef void RetVal_Round;
496 typedef void RetVal_Round2;
500 mpfr_set_ui(d.d_value, v, MPFR_RNDN);
508 static void convert_frac(
Real & d,
unsigned int v1,
unsigned int v2,
const RealContext & c)
510 mpfr_set_ui(d.d_value, v1, MPFR_RNDN);
511 Real t((
unsigned long)v2, c);
517 Real t1((
unsigned long)v1, c), t2((
unsigned long)v2, c);
528 typedef void RetVal_Floor;
529 typedef void RetVal_Ceil;
530 typedef void RetVal_Round;
531 typedef void RetVal_Round2;
535 mpfr_set_si(d.d_value, v, MPFR_RNDN);
543 static void convert_frac(
Real & d,
signed long v1,
signed long v2,
const RealContext & c)
545 mpfr_set_si(d.d_value, v1, MPFR_RNDN);
552 Real t1(v1, c), t2(v2, c);
563 typedef void RetVal_Floor;
564 typedef void RetVal_Ceil;
565 typedef void RetVal_Round;
566 typedef void RetVal_Round2;
570 mpfr_set_ui(d.d_value, v, MPFR_RNDN);
578 static void convert_frac(
Real & d,
unsigned long v1,
unsigned long v2,
const RealContext & c)
580 mpfr_set_ui(d.d_value, v1, MPFR_RNDN);
587 Real t1(v1, c), t2(v2, c);
598 typedef void RetVal_Floor;
599 typedef void RetVal_Ceil;
600 typedef void RetVal_Round;
601 typedef void RetVal_Round2;
605 Real::mpfr_set_ll(d.d_value, v, MPFR_RNDN);
613 static void convert_frac(
Real & d,
long long v1,
long long v2,
const RealContext & c)
615 Real::mpfr_set_ll(d.d_value, v1, MPFR_RNDN);
622 Real t1(v1, c), t2(v2, c);
633 typedef void RetVal_Floor;
634 typedef void RetVal_Ceil;
635 typedef void RetVal_Round;
636 typedef void RetVal_Round2;
640 mpfr_set_d(d.d_value, v, MPFR_RNDN);
648 static void convert_frac(
Real & d,
float v1,
float v2,
const RealContext & c)
650 mpfr_set_d(d.d_value, v1, MPFR_RNDN);
657 Real t1(v1, c), t2(v2, c);
668 typedef void RetVal_Floor;
669 typedef void RetVal_Ceil;
670 typedef void RetVal_Round;
671 typedef void RetVal_Round2;
675 mpfr_set_d(d.d_value, v, MPFR_RNDN);
683 static void convert_frac(
Real & d,
double v1,
double v2,
const RealContext & c)
685 mpfr_set_d(d.d_value, v1, MPFR_RNDN);
692 Real t1(v1, c), t2(v2, c);
703 typedef void RetVal_Floor;
704 typedef void RetVal_Ceil;
705 typedef void RetVal_Round;
706 typedef void RetVal_Round2;
710 mpfr_set_ld(d.d_value, v, MPFR_RNDN);
718 static void convert_frac(
Real & d,
long double v1,
long double v2,
const RealContext & c)
720 mpfr_set_ld(d.d_value, v1, MPFR_RNDN);
727 Real t1(v1, c), t2(v2, c);
739 typedef void RetVal_Floor;
740 typedef void RetVal_Ceil;
741 typedef void RetVal_Round;
742 typedef void RetVal_Round2;
746 mpfr_set_z(d.d_value, v.d_value, MPFR_RNDN);
751 return RetVal(expressions::make_expression<IntegerContext>(v), c);
756 mpfr_set_z(d.d_value, v1.d_value, MPFR_RNDN);
763 Real t1(v1, c), t2(v2, c);
774 typedef void RetVal_Frac;
786 mpfr_get_z(d.d_value, v.d_value, MPFR_RNDD);
791 return RetVal(expressions::make_expression<RealContext>(v), implementation::g_intcontext);
796 mpfr_get_z(d.d_value, v.d_value, MPFR_RNDD);
801 return RetVal_Floor(expressions::make_expression<RealContext>(v), implementation::g_intcontext);
806 mpfr_get_z(d.d_value, v.d_value, MPFR_RNDN);
811 return RetVal_Round(expressions::make_expression<RealContext>(v), implementation::g_intcontext);
816 mpfr_get_z(d.d_value, v.d_value, MPFR_RNDN);
819 mpfr_get_z(tmp, v.d_value, MPFR_RNDD);
820 up = mpz_cmp(tmp, d.d_value) != 0;
826 return RetVal_Round2(expressions::make_expression<RealContext>(v),
834 mpfr_get_z(d.d_value, v.d_value, MPFR_RNDU);
839 return RetVal_Ceil(expressions::make_expression<RealContext>(v), implementation::g_intcontext);
852 typedef void RetVal_Floor;
853 typedef void RetVal_Ceil;
854 typedef void RetVal_Round;
855 typedef void RetVal_Round2;
886 static int toInt(
const Real & v)
888 return mpfr_get_si(v.d_value, MPFR_RNDD);
891 static int toInt_Floor(
const Real & v)
893 return mpfr_get_si(v.d_value, MPFR_RNDD);
896 static int toInt_Round(
const Real & v)
898 return mpfr_get_si(v.d_value, MPFR_RNDN);
901 static int toInt_Round(
const Real & v,
bool & up)
903 int r = mpfr_get_si(v.d_value, MPFR_RNDN);
904 up = mpfr_cmp_si(v.d_value, r) < 0;
908 static int toInt_Ceil(
const Real & v)
910 return mpfr_get_si(v.d_value, MPFR_RNDU);
913 static unsigned int toUInt(
const Real & v)
915 return mpfr_get_ui(v.d_value, MPFR_RNDD);
918 static unsigned int toUInt_Floor(
const Real & v)
920 return mpfr_get_ui(v.d_value, MPFR_RNDD);
923 static unsigned int toUInt_Round(
const Real & v)
925 return mpfr_get_ui(v.d_value, MPFR_RNDN);
928 static unsigned int toUInt_Round(
const Real & v,
bool & up)
930 unsigned int r = mpfr_get_ui(v.d_value, MPFR_RNDN);
931 up = mpfr_cmp_ui(v.d_value, r) < 0;
935 static unsigned int toUInt_Ceil(
const Real & v)
937 return mpfr_get_ui(v.d_value, MPFR_RNDU);
940 static long toLong(
const Real & v)
942 return mpfr_get_si(v.d_value, MPFR_RNDD);
945 static long toLong_Floor(
const Real & v)
947 return mpfr_get_si(v.d_value, MPFR_RNDD);
950 static long toLong_Round(
const Real & v)
952 return mpfr_get_si(v.d_value, MPFR_RNDN);
955 static long toLong_Round(
const Real & v,
bool & up)
957 long r = mpfr_get_si(v.d_value, MPFR_RNDN);
958 up = mpfr_cmp_si(v.d_value, r) < 0;
962 static long toLong_Ceil(
const Real & v)
964 return mpfr_get_si(v.d_value, MPFR_RNDU);
967 static unsigned long toULong(
const Real & v)
969 return mpfr_get_ui(v.d_value, MPFR_RNDD);
972 static unsigned long toULong_Floor(
const Real & v)
974 return mpfr_get_ui(v.d_value, MPFR_RNDD);
977 static unsigned long toULong_Round(
const Real & v)
979 return mpfr_get_ui(v.d_value, MPFR_RNDN);
982 static unsigned long toULong_Round(
const Real & v,
bool & up)
984 unsigned long r = mpfr_get_ui(v.d_value, MPFR_RNDN);
985 up = mpfr_cmp_ui(v.d_value, r) < 0;
989 static unsigned long toULong_Ceil(
const Real & v)
991 return mpfr_get_ui(v.d_value, MPFR_RNDU);
994 static long long toLongLong(
const Real & v)
996 return Real::mpfr_get_ll(v.d_value, MPFR_RNDD);
999 static long long toLongLong_Floor(
const Real & v)
1001 return Real::mpfr_get_ll(v.d_value, MPFR_RNDD);
1004 static long long toLongLong_Round(
const Real & v)
1006 return Real::mpfr_get_ll(v.d_value, MPFR_RNDN);
1009 static long long toLongLong_Round(
const Real & v,
bool & up)
1011 return Real::mpfr_get_ll(v.d_value, MPFR_RNDN, up);
1014 static long long toLongLong_Ceil(
const Real & v)
1016 return Real::mpfr_get_ll(v.d_value, MPFR_RNDU);
1019 static float toFloat(
const Real & v)
1021 return mpfr_get_d(v.d_value, MPFR_RNDN);
1024 static double toDouble(
const Real & v)
1026 return mpfr_get_d(v.d_value, MPFR_RNDN);
1029 static long double toLongDouble(
const Real & v)
1031 return mpfr_get_ld(v.d_value, MPFR_RNDN);
1038 template<
class Data,
template<
typename,
typename>
class Op>
1039 struct type_traits<expressions::Expression<IntegerContext, Data, Op> >
1045 is_realtype =
false,
1048 is_cpp_string =
false,
1049 is_c_string =
false,
1051 has_uniform_rng =
true,
1055 has_infinity =
false,
1056 is_variable_precision =
false,
1057 has_squareroot =
false,
1058 has_full_power =
false,
1059 has_special_fns =
false,
1060 has_huge_exponent =
false,
1061 has_constants =
false,
1062 has_trigonometric =
false
1070 template<
class Data,
template<
typename,
typename>
class Op>
1080 is_cpp_string =
false,
1081 is_c_string =
false,
1083 has_uniform_rng =
true,
1087 has_infinity =
true,
1088 is_variable_precision =
true,
1089 has_squareroot =
true,
1090 has_full_power =
true,
1091 has_special_fns =
true,
1092 has_huge_exponent =
true,
1093 has_constants =
true,
1094 has_trigonometric =
true
1103 namespace implementation
1134 typedef std::string RetVal;
1136 static RetVal convert(
const Integer &);
1137 static RetVal convert(
const Integer &,
unsigned);
1138 static void convert(std::string &,
const Integer &);
1139 static void convert(std::string &,
const Integer &,
unsigned);
1149 static bool convert(
Real & res,
const std::string & s,
const RealContext & c);
1150 static bool convert(
Real & res,
const char * s,
const RealContext & c);
1171 typedef std::string RetVal;
1173 static RetVal convert(
const Real &);
1174 static RetVal convert(
const Real &,
unsigned);
1175 static void convert(std::string &,
const Real &);
1176 static void convert(std::string &,
const Real &,
unsigned);
1179 #define MAKE_INTEGER_DEFS(Op1, Op2) \
1181 struct binary_operation_impl<Integer, Integer, Op1> \
1183 enum { supported = true, intermediate_expression = true }; \
1184 typedef expressions::Expression<IntegerContext, std::pair<expressions::Wrapper<IntegerContext>, \
1185 expressions::Wrapper<IntegerContext> >, Op2> IntermediateType; \
1186 typedef Integer ResultType; \
1189 template<template<typename, typename> class O1, typename D1> \
1190 struct binary_operation_impl<expressions::Expression<IntegerContext, D1, O1>, Integer, Op1> \
1192 enum { supported = true, intermediate_expression = true }; \
1193 typedef expressions::Expression<IntegerContext, std::pair<expressions::Expression<IntegerContext, D1, O1>, \
1194 expressions::Wrapper<IntegerContext> >, Op2> IntermediateType; \
1195 typedef Integer ResultType; \
1198 template<template<typename, typename> class O2, typename D2> \
1199 struct binary_operation_impl<Integer, expressions::Expression<IntegerContext, D2, O2>, Op1> \
1201 enum { supported = true, intermediate_expression = true }; \
1202 typedef expressions::Expression<IntegerContext, std::pair<expressions::Wrapper<IntegerContext>, \
1203 expressions::Expression<IntegerContext, D2, O2> >, Op2> IntermediateType; \
1204 typedef Integer ResultType; \
1207 template<template<typename, typename> class O1, typename D1, template<typename, typename> class O2, typename D2> \
1208 struct binary_operation_impl<expressions::Expression<IntegerContext, D1, O1>, expressions::Expression<IntegerContext, D2, O2>, Op1> \
1210 enum { supported = true, intermediate_expression = true }; \
1211 typedef expressions::Expression<IntegerContext, std::pair<expressions::Expression<IntegerContext, D1, O1>, \
1212 expressions::Expression<IntegerContext, D2, O2> >, Op2> IntermediateType; \
1213 typedef Integer ResultType; \
1217 MAKE_INTEGER_DEFS(arithmetic::op::subtraction, expressions::SubOp)
1218 MAKE_INTEGER_DEFS(arithmetic::op::multiplication, expressions::MulOp)
1219 MAKE_INTEGER_DEFS(arithmetic::op::division, expressions::DivOp)
1220 MAKE_INTEGER_DEFS(arithmetic::op::modulo, expressions::ModOp)
1221 #undef MAKE_INTEGER_DEFS
1226 enum { supported =
true, intermediate_expression =
true };
1232 template<
template<
typename,
typename>
class O,
class D>
1235 enum { supported =
true, intermediate_expression =
true };
1241 #define MAKE_REAL_DEFS(Op1, Op2) \
1243 struct binary_operation_impl<Real, Real, Op1> \
1245 enum { supported = true, intermediate_expression = true }; \
1246 typedef expressions::Expression<RealContext, std::pair<expressions::Wrapper<RealContext>, \
1247 expressions::Wrapper<RealContext> >, Op2> IntermediateType; \
1248 typedef Real ResultType; \
1251 template<template<typename, typename> class O1, typename D1> \
1252 struct binary_operation_impl<expressions::Expression<RealContext, D1, O1>, Real, Op1> \
1254 enum { supported = true, intermediate_expression = true }; \
1255 typedef expressions::Expression<RealContext, std::pair<expressions::Expression<RealContext, D1, O1>, \
1256 expressions::Wrapper<RealContext> >, Op2> IntermediateType; \
1257 typedef Real ResultType; \
1260 template<template<typename, typename> class O2, typename D2> \
1261 struct binary_operation_impl<Real, expressions::Expression<RealContext, D2, O2>, Op1> \
1263 enum { supported = true, intermediate_expression = true }; \
1264 typedef expressions::Expression<RealContext, std::pair<expressions::Wrapper<RealContext>, \
1265 expressions::Expression<RealContext, D2, O2> >, Op2> IntermediateType; \
1266 typedef Real ResultType; \
1269 template<template<typename, typename> class O1, typename D1, template<typename, typename> class O2, typename D2> \
1270 struct binary_operation_impl<expressions::Expression<RealContext, D1, O1>, expressions::Expression<RealContext, D2, O2>, Op1> \
1272 enum { supported = true, intermediate_expression = true }; \
1273 typedef expressions::Expression<RealContext, std::pair<expressions::Expression<RealContext, D1, O1>, \
1274 expressions::Expression<RealContext, D2, O2> >, Op2> IntermediateType; \
1275 typedef Real ResultType; \
1279 MAKE_REAL_DEFS(arithmetic::op::subtraction, expressions::SubOp)
1280 MAKE_REAL_DEFS(arithmetic::op::multiplication, expressions::MulOp)
1281 MAKE_REAL_DEFS(arithmetic::op::division, expressions::DivOp)
1282 MAKE_REAL_DEFS(arithmetic::op::modulo, expressions::ModOp)
1283 #undef MAKE_REAL_DEFS
1288 enum { supported =
true, intermediate_expression =
true };
1293 template<
template<
typename,
typename>
class O,
class D>
1296 enum { supported =
true, intermediate_expression =
true };
Returns the sum of the operands.
Converts the argument to the destination type. Uses the context stored in the operator.
Simply provides the data without any modifications.
Provides information on the result of an unary arithmetic operation.
Returns the negative of the operand.
Provides conversion implementation from type SourceType to DestContext::Type.
void convert(typename DestContext::Type &dst, const SourceType &src, const DestContext &context)
Converts the value in src to the type described by context and stores the result in dst...
Provides facilities to convert strings to types.
Provides facilities to convert types to std::strings.
Converts the argument to the destination type by rounding. Uses the context stored in the operator an...
Implementation backend for conversions from context types to native types.
Converts the argument to the destination type by rounding down (floor). Uses the context stored in th...
Represents an expression.
Represents an arbitrary precision floating point value.
Converts the argument to the destination type by rounding up (ceil). Uses the context stored in the o...
Represents an arithmetic context for arbitrary precision floating point values.
Converts the argument to the destination type by rounding. Uses the context stored in the operator...
Provides information on arithmetic (and string) types.
Represents an arbitrary precision integer.
Wraps a variable to behave similarly to an Expression<> object.
Represents an arithmetic context for arbitrary precision integer.