diff --git a/build.vc11/mpir.net/mpir.net/mpir.net.vcxproj b/build.vc11/mpir.net/mpir.net/mpir.net.vcxproj
index bc5f01cb..aa1c43f7 100644
--- a/build.vc11/mpir.net/mpir.net/mpir.net.vcxproj
+++ b/build.vc11/mpir.net/mpir.net/mpir.net.vcxproj
@@ -150,7 +150,6 @@
-
@@ -170,6 +169,9 @@
+
+
+
diff --git a/build.vc11/mpir.net/mpir.net/mpir.net.vcxproj.filters b/build.vc11/mpir.net/mpir.net/mpir.net.vcxproj.filters
index d3393199..a3d009fc 100644
--- a/build.vc11/mpir.net/mpir.net/mpir.net.vcxproj.filters
+++ b/build.vc11/mpir.net/mpir.net/mpir.net.vcxproj.filters
@@ -44,9 +44,6 @@
Source Files
-
- Source Files
-
Source Files
@@ -67,4 +64,9 @@
Resource Files
+
+
+ Header Files
+
+
\ No newline at end of file
diff --git a/mpir.net/mpir.net-tests/Utilities/Accessors.cs b/mpir.net/mpir.net-tests/Utilities/Accessors.cs
index 6dbbc2bf..b11b464d 100644
--- a/mpir.net/mpir.net-tests/Utilities/Accessors.cs
+++ b/mpir.net/mpir.net-tests/Utilities/Accessors.cs
@@ -26,7 +26,7 @@ using System.Reflection;
namespace MPIR.Tests
{
- internal static class Accessors
+ internal static class Accessors
{
private static readonly ConstructorInfo _intPtrConstructor;
private static readonly FieldInfo _getValue;
@@ -40,45 +40,127 @@ namespace MPIR.Tests
private static FieldInfo GetAccessor(string name)
{
- return typeof(HugeInt).GetField(name, BindingFlags.NonPublic | BindingFlags.Instance);
+ return typeof(T).GetField(name, BindingFlags.NonPublic | BindingFlags.Instance);
}
- public static int NumberOfLimbsAllocated(this HugeInt x)
- {
- if (x._value() == IntPtr.Zero)
- return 0;
-
- unsafe
- {
- return ((int*)x._value().ToPointer())[0];
- }
- }
-
- public static int NumberOfLimbsUsed(this HugeInt x)
- {
- if (x._value() == IntPtr.Zero)
- return 0;
-
- unsafe
- {
- return ((int*)x._value().ToPointer())[1];
- }
- }
-
- public static IntPtr Limbs(this HugeInt x)
- {
- if (x._value() == IntPtr.Zero)
- return IntPtr.Zero;
-
- unsafe
- {
- return new IntPtr(((void**)x._value().ToPointer())[1]);
- }
- }
-
- public static IntPtr _value(this HugeInt x)
+ internal static IntPtr _value(T x)
{
return (IntPtr)_intPtrConstructor.Invoke(new object[] { _getValue.GetValue(x) });
}
}
+
+ internal static class IntAccessors
+ {
+ internal static IntPtr _value(this HugeInt x)
+ {
+ return Accessors._value(x);
+ }
+
+ internal static int NumberOfLimbsAllocated(this HugeInt x)
+ {
+ if (_value(x) == IntPtr.Zero)
+ return 0;
+
+ unsafe
+ {
+ return ((int*)_value(x).ToPointer())[0];
+ }
+ }
+
+ internal static int NumberOfLimbsUsed(this HugeInt x)
+ {
+ if (_value(x) == IntPtr.Zero)
+ return 0;
+
+ unsafe
+ {
+ return ((int*)_value(x).ToPointer())[1];
+ }
+ }
+
+ internal static IntPtr Limbs(this HugeInt x)
+ {
+ if (_value(x) == IntPtr.Zero)
+ return IntPtr.Zero;
+
+ unsafe
+ {
+ return new IntPtr(((void**)_value(x).ToPointer())[1]);
+ }
+ }
+ }
+
+ internal static class RationalAccessors
+ {
+ internal static IntPtr _value(this HugeRational x)
+ {
+ return Accessors._value(x);
+ }
+
+ internal static int NumeratorNumberOfLimbsAllocated(this HugeRational x)
+ {
+ if (_value(x) == IntPtr.Zero)
+ return 0;
+
+ unsafe
+ {
+ return ((int*)_value(x).ToPointer())[0];
+ }
+ }
+
+ internal static int NumeratorNumberOfLimbsUsed(this HugeRational x)
+ {
+ if (_value(x) == IntPtr.Zero)
+ return 0;
+
+ unsafe
+ {
+ return ((int*)_value(x).ToPointer())[1];
+ }
+ }
+
+ internal static IntPtr NumeratorLimbs(this HugeRational x)
+ {
+ if (_value(x) == IntPtr.Zero)
+ return IntPtr.Zero;
+
+ unsafe
+ {
+ return new IntPtr(((void**)_value(x).ToPointer())[1]);
+ }
+ }
+
+ internal static int DenominatorNumberOfLimbsAllocated(this HugeRational x)
+ {
+ if (_value(x) == IntPtr.Zero)
+ return 0;
+
+ unsafe
+ {
+ return ((int*)_value(x).ToPointer())[4];
+ }
+ }
+
+ internal static int DenominatorNumberOfLimbsUsed(this HugeRational x)
+ {
+ if (_value(x) == IntPtr.Zero)
+ return 0;
+
+ unsafe
+ {
+ return ((int*)_value(x).ToPointer())[5];
+ }
+ }
+
+ internal static IntPtr DenominatorLimbs(this HugeRational x)
+ {
+ if (_value(x) == IntPtr.Zero)
+ return IntPtr.Zero;
+
+ unsafe
+ {
+ return new IntPtr(((void**)_value(x).ToPointer())[3]);
+ }
+ }
+ }
}
diff --git a/mpir.net/mpir.net/Common.h b/mpir.net/mpir.net/Common.h
index 609e96ee..6e6e74e6 100644
--- a/mpir.net/mpir.net/Common.h
+++ b/mpir.net/mpir.net/Common.h
@@ -19,104 +19,134 @@ along with the MPIR Library. If not, see http://www.gnu.org/licenses/.
#pragma once
-#define DEFINE_ASSIGNMENT_PROLOG(name) void Mpir##name##Expression::AssignTo(mpz_ptr destination)
+#pragma region misc macros
-#define DEFINE_UNARY_ASSIGNMENT_REF(name, typeAbbr, operation) \
- DEFINE_ASSIGNMENT_PROLOG(name##typeAbbr) \
- { \
- Operand->AssignTo(destination); \
- operation(destination, destination); \
- }
+#define LIT2(x) x
+#define LIT(x) LIT2(x)
+#define IS_NULL(a) (Object::ReferenceEquals(a, nullptr))
+#define PIN(x) pin_ptr pinptr##x = &x[0]; void* pinned_##x = pinptr##x;
-#define DEFINE_UNARY_ASSIGNMENT_VAL(name, typeAbbr, operation) \
- DEFINE_ASSIGNMENT_PROLOG(name##typeAbbr) \
- { \
- operation(destination, Operand); \
- }
+#define IN_CONTEXT_1(a) \
+ EvaluationContext context; \
+ a->AssignTo(context)
-#define DEFINE_BINARY_ASSIGNMENT_REF_REF(name, typeAbbr, operation) \
- DEFINE_ASSIGNMENT_PROLOG(name##typeAbbr##typeAbbr) \
- { \
- IN_CONTEXT(Left, Right); \
- operation(destination, context.Args[0], context.Args[1]); \
- }
+#define IN_CONTEXT_2(a, b) \
+ EvaluationContext context; \
+ a->AssignTo(context); \
+ b->AssignTo(context)
-#define DEFINE_BINARY_ASSIGNMENT_REF_VAL(name, leftTypeAbbr, rightTypeAbbr, operation) \
- DEFINE_ASSIGNMENT_PROLOG(name##leftTypeAbbr##rightTypeAbbr) \
- { \
- Left->AssignTo(destination); \
- operation(destination, destination, Right); \
- }
+#define IN_CONTEXT_3(a, b, c) \
+ EvaluationContext context; \
+ a->AssignTo(context); \
+ b->AssignTo(context); \
+ c->AssignTo(context)
-#define DEFINE_BINARY_ASSIGNMENT_VAL_REF(name, leftTypeAbbr, rightTypeAbbr, operation) \
- DEFINE_ASSIGNMENT_PROLOG(name##leftTypeAbbr##rightTypeAbbr) \
- { \
- Right->AssignTo(destination); \
- operation(destination, Left, destination); \
- }
+#define COUNT_ARGS_IMPL2(_1, _2, _3, name, ...) name
+#define COUNT_ARGS_IMPL(args) COUNT_ARGS_IMPL2 args
+#define COUNT_ARGS(...) COUNT_ARGS_IMPL((__VA_ARGS__, 3, 2, 1))
+#define MACRO_CHOOSE2(prefix, number) prefix##number
+#define MACRO_CHOOSE1(prefix, number) MACRO_CHOOSE2(prefix, number)
+#define MACRO_CHOOSE(prefix, number) MACRO_CHOOSE1(prefix, number)
+#define MACRO_GLUE(x, y) x y
+#define IN_CONTEXT(...) MACRO_GLUE(MACRO_CHOOSE(IN_CONTEXT_, COUNT_ARGS(__VA_ARGS__)), (__VA_ARGS__))
-#define DEFINE_BINARY_ASSIGNMENT_VAL_VAL(name, leftTypeAbbr, rightTypeAbbr, operation) \
- DEFINE_ASSIGNMENT_PROLOG(name##leftTypeAbbr##rightTypeAbbr) \
- { \
- operation(destination, Left, Right); \
- }
+#define TYPE_FOR_ABBR_Int HugeInt^
+#define TYPE_FOR_ABBR_Expr IntegerExpression^
+#define TYPE_FOR_ABBR_Si mpir_si
+#define TYPE_FOR_ABBR_Ui mpir_ui
+#define TYPE_FOR_ABBR_Bits mp_bitcnt_t
+#define TYPE_FOR_ABBR_Rnd MpirRandom^
-#define DEFINE_BINARY_ASSIGNMENT_REF_SI(name, leftTypeAbbr, rightTypeAbbr, positiveOp, negativeOp) \
- DEFINE_ASSIGNMENT_PROLOG(name##leftTypeAbbr##rightTypeAbbr) \
- { \
- Left->AssignTo(destination); \
- if (Right >= 0) \
- positiveOp(destination, destination, (mpir_ui)Right); \
- else \
- negativeOp(destination, destination, (mpir_ui)-Right); \
- }
+#pragma endregion
-#define DEFINE_BINARY_ASSIGNMENT_SI_REF(name, leftTypeAbbr, rightTypeAbbr, positiveOp, negativeOp1, negativeOp2) \
- DEFINE_ASSIGNMENT_PROLOG(name##leftTypeAbbr##rightTypeAbbr) \
- { \
- Right->AssignTo(destination); \
- if (Left >= 0) \
- positiveOp(destination, (mpir_ui)Left, destination); \
- else \
- { \
- negativeOp1(destination, destination, (mpir_ui)-Left); \
- negativeOp2(destination, destination); \
- } \
- }
+#pragma region enums
-#define DEFINE_TERNARY_ASSIGNMENT_REF_REF_REF(name, typeAbbr, operation) \
- DEFINE_ASSIGNMENT_PROLOG(name##typeAbbr##typeAbbr##typeAbbr) \
- { \
- IN_CONTEXT(Left, Middle, Right); \
- operation(destination, context.Args[0], context.Args[1], context.Args[2]); \
- }
+namespace MPIR
+{
+ ///
+ /// This enum defines the rounding modes MPIR supports. Division and modulo operations take an optional rounding mode parameter, or use the default, which is set in the static MpirSettings class.
+ ///
+ public enum class RoundingModes
+ {
+ /// Rounding mode is unspecified. Use a higher level default if available, fall back to Truncate.
+ Default,
+ /// Truncate. Quotient is rounded toward zero, and remainder has the same sign as the source number.
+ Truncate,
+ /// Round up. Quotient is rounded toward +infinity, and remainder has the opposite sign to the divisor.
+ Ceiling,
+ /// Round down. Quotient is rounded toward -infinity, and remainder has the sames sign as the divisor.
+ Floor,
+ };
-#define DEFINE_TERNARY_ASSIGNMENT_REF_VAL_REF(name, leftT, middleT, rightT, operation) \
- DEFINE_ASSIGNMENT_PROLOG(name##leftT##middleT##rightT) \
- { \
- IN_CONTEXT(Left, Right); \
- operation(destination, context.Args[0], Middle, context.Args[1]); \
- }
+ ///
+ /// This enum defines the limb order used when importing or exporting a number.
+ ///
+ public enum class LimbOrder : __int8
+ {
+ /// Most significant limb comes first.
+ MostSignificantFirst = 1,
+ /// Least significant limb comes first.
+ LeastSignificantFirst = -1,
+ };
-enum EvaluationOptions : __int8
+ ///
+ /// This enum defines the byte order within each limb when importing or exporting a number.
+ ///
+ public enum class Endianness : __int8
+ {
+ /// The native byte order of the CPU is used.
+ Native = 0,
+ /// Most significant byte comes first in a limb.
+ BigEndian = 1,
+ /// Least significant byte comes first in a limb.
+ LittleEndian = -1,
+ };
+}
+
+enum EvaluationOptions : __int32
{
None = 0x0,
- Temp1Initialized = 0x1,
- Temp2Initialized = 0x2,
- Temp3Initialized = 0x4,
+
+ IntInitialized = 0x1,
+ Temp1InitializedInt = IntInitialized,
+ Temp2InitializedInt = IntInitialized << 1,
+ Temp3InitializedInt = IntInitialized << 2,
+
+ RationalInitialized = 0x10,
+ Temp1InitializedRational = RationalInitialized,
+ Temp2InitializedRational = RationalInitialized << 1,
+ Temp3InitializedRational = RationalInitialized << 2,
+
+ FloatInitialized = 0x100,
+ Temp1InitializedFloat = FloatInitialized,
+ Temp2InitializedFloat = FloatInitialized << 1,
+ Temp3InitializedFloat = FloatInitialized << 2,
};
+#pragma endregion
+
struct EvaluationContext
{
public:
- __mpz_struct Temp[3];
- mpz_ptr Args[3];
+ union
+ {
+ __mpz_struct Integer;
+ __mpq_struct Rational;
+ __mpf_struct Float;
+ }
+ Temp[3];
+ union
+ {
+ mpz_ptr IntArgs[3];
+ mpq_ptr RationalArgs[3];
+ mpf_ptr FloatArgs[3];
+ };
union
{
struct
{
- unsigned __int8 Index;
EvaluationOptions Options;
+ unsigned __int8 Index;
};
__int64 Zero;
};
@@ -128,11 +158,25 @@ struct EvaluationContext
~EvaluationContext()
{
- if(Options & EvaluationOptions::Temp1Initialized)
- mpz_clear(Args[0]);
- if(Options & EvaluationOptions::Temp2Initialized)
- mpz_clear(Args[1]);
- if(Options & EvaluationOptions::Temp3Initialized)
- mpz_clear(Args[2]);
+ if(Options & EvaluationOptions::Temp1InitializedInt)
+ mpz_clear(IntArgs[0]);
+ if(Options & EvaluationOptions::Temp2InitializedInt)
+ mpz_clear(IntArgs[1]);
+ if(Options & EvaluationOptions::Temp3InitializedInt)
+ mpz_clear(IntArgs[2]);
+
+ if(Options & EvaluationOptions::Temp1InitializedRational)
+ mpq_clear(RationalArgs[0]);
+ if(Options & EvaluationOptions::Temp2InitializedRational)
+ mpq_clear(RationalArgs[1]);
+ if(Options & EvaluationOptions::Temp3InitializedRational)
+ mpq_clear(RationalArgs[2]);
+
+ if(Options & EvaluationOptions::Temp1InitializedFloat)
+ mpf_clear(FloatArgs[0]);
+ if(Options & EvaluationOptions::Temp2InitializedFloat)
+ mpf_clear(FloatArgs[1]);
+ if(Options & EvaluationOptions::Temp3InitializedFloat)
+ mpf_clear(FloatArgs[2]);
}
};
\ No newline at end of file
diff --git a/mpir.net/mpir.net/ExpressionMacros.h b/mpir.net/mpir.net/ExpressionMacros.h
new file mode 100644
index 00000000..e9665111
--- /dev/null
+++ b/mpir.net/mpir.net/ExpressionMacros.h
@@ -0,0 +1,259 @@
+/*
+Copyright 2014 Alex Dyachenko
+
+This file is part of the MPIR Library.
+
+The MPIR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published
+by the Free Software Foundation; either version 3 of the License, or (at
+your option) any later version.
+
+The MPIR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the MPIR Library. If not, see http://www.gnu.org/licenses/.
+*/
+
+#pragma region Expression macros
+
+//defines a unary expression class
+#define DEFINE_UNARY_EXPRESSION(base, name, type) \
+private ref class MPEXPR(name) : base \
+{ \
+ internal: \
+ type Operand; \
+ virtual void AssignTo(MP(ptr) destination) override; \
+ MPEXPR(name)(type operand) \
+ { \
+ Operand = operand; \
+ } \
+};
+
+//defines a binary expression class
+#define DEFINE_BINARY_EXPRESSION(base, name, leftType, rightType) \
+private ref class MPEXPR(name) : base \
+{ \
+ internal: \
+ leftType Left; \
+ rightType Right; \
+ virtual void AssignTo(MP(ptr) destination) override; \
+ MPEXPR(name)(leftType left, rightType right) \
+ { \
+ Left = left; \
+ Right = right; \
+ } \
+};
+
+//defines a ternary expression class
+#define DEFINE_TERNARY_EXPRESSION(base, name, leftType, middleType, rightType) \
+private ref class MPEXPR(name) : base \
+{ \
+ internal: \
+ leftType Left; \
+ middleType Middle; \
+ rightType Right; \
+ virtual void AssignTo(MP(ptr) destination) override; \
+ MPEXPR(name)(leftType left, middleType middle, rightType right) \
+ { \
+ Left = left; \
+ Middle = middle; \
+ Right = right; \
+ } \
+};
+
+//unary expressions
+#define DEFINE_UNARY_EXPRESSION_WITH_ONE(base, name, typeAbbr) \
+ DEFINE_UNARY_EXPRESSION(base, name##typeAbbr, MPEXPR_NAME^)
+
+#define DEFINE_UNARY_EXPRESSION_WITH_BUILT_INS_ONLY(base, name, typeAbbr) \
+ DEFINE_UNARY_EXPRESSION(base, name##typeAbbr, TYPE_FOR_ABBR_##typeAbbr)
+
+//binary expressions
+#define DEFINE_BINARY_EXPRESSION_WITH_BUILT_INS_ONLY(base, name, leftTypeAbbr, rightTypeAbbr) \
+ DEFINE_BINARY_EXPRESSION(base, name##leftTypeAbbr##rightTypeAbbr, TYPE_FOR_ABBR_##leftTypeAbbr, TYPE_FOR_ABBR_##rightTypeAbbr)
+
+#define DEFINE_BINARY_EXPRESSION_WITH_TWO(base, name, typeAbbr) \
+ DEFINE_BINARY_EXPRESSION(base, name##typeAbbr##typeAbbr, MPEXPR_NAME^, MPEXPR_NAME^)
+
+#define DEFINE_BINARY_EXPRESSION_WITH_BUILT_IN_RIGHT(base, name, leftTypeAbbr, rightTypeAbbr) \
+ DEFINE_BINARY_EXPRESSION(base, name##leftTypeAbbr##rightTypeAbbr, MPEXPR_NAME^, TYPE_FOR_ABBR_##rightTypeAbbr)
+
+#define DEFINE_BINARY_EXPRESSION_WITH_BUILT_IN_LEFT(base, name, leftTypeAbbr, rightTypeAbbr) \
+ DEFINE_BINARY_EXPRESSION(base, name##leftTypeAbbr##rightTypeAbbr, TYPE_FOR_ABBR_##leftTypeAbbr, MPEXPR_NAME^)
+
+//ternary expressions
+#define DEFINE_TERNARY_EXPRESSION_WITH_THREE(base, name, typeAbbr) \
+ DEFINE_TERNARY_EXPRESSION(base, name##typeAbbr##typeAbbr##typeAbbr, MPEXPR_NAME^, MPEXPR_NAME^, MPEXPR_NAME^)
+
+#define DEFINE_TERNARY_EXPRESSION_WITH_BUILT_IN_MIDDLE(base, name, leftTypeAbbr, middleTypeAbbr, rightTypeAbbr) \
+ DEFINE_TERNARY_EXPRESSION(base, name##leftTypeAbbr##middleTypeAbbr##rightTypeAbbr, MPEXPR_NAME^, TYPE_FOR_ABBR_##middleTypeAbbr, MPEXPR_NAME^)
+
+#pragma endregion
+
+#pragma region Method macros
+
+//void functions
+#define MAKE_VOID_FUNCTION(base, action, op, type) \
+ MAKE_VOID_FUNCTION_##action(base, op, op##type)
+
+#define MAKE_VOID_FUNCTION_DECLARE(base, op, result) \
+ base^ op();
+
+#define MAKE_VOID_FUNCTION_DEFINE(base, op, result) \
+ base^ MPEXPR_NAME::op() { return gcnew MPEXPR(result)(this); }
+
+//one-arg functions
+#define MAKE_FUNCTION_WITH_ONE(base, action, op, argTypeAbbr) \
+ MAKE_FUNCTION_WITH_ONE_##action(base, op, Expr, op##Int##argTypeAbbr)
+
+#define MAKE_FUNCTION_WITH_LIMB(base, action, op, argTypeAbbr) \
+ MAKE_FUNCTION_WITH_ONE_##action(base, op, argTypeAbbr, op##Int##argTypeAbbr)
+
+#define MAKE_FUNCTION_WITH_ONE_DECLARE(base, op, argTypeAbbr, result) \
+ base^ op(TYPE_FOR_ABBR_##argTypeAbbr a);
+
+#define MAKE_FUNCTION_WITH_ONE_DEFINE(base, op, argTypeAbbr, result) \
+ base^ MPEXPR_NAME::op(TYPE_FOR_ABBR_##argTypeAbbr a) { return gcnew MPEXPR(result)(this, a); }
+
+//two-arg functions
+#define MAKE_FUNCTION_WITH_TWO(base, action, op, leftTypeAbbr, rightTypeAbbr) \
+ MAKE_FUNCTION_WITH_TWO_##action(base, op, Expr, Expr, op##Int##leftTypeAbbr##rightTypeAbbr)
+
+#define MAKE_FUNCTION_WITH_TWO_LLIMB(base, action, op, leftTypeAbbr, rightTypeAbbr) \
+ MAKE_FUNCTION_WITH_TWO_##action(base, op, leftTypeAbbr, Expr, op##Int##leftTypeAbbr##rightTypeAbbr)
+
+#define MAKE_FUNCTION_WITH_TWO_DECLARE(base, op, leftTypeAbbr, rightTypeAbbr, result) \
+ base^ op(TYPE_FOR_ABBR_##leftTypeAbbr a, TYPE_FOR_ABBR_##rightTypeAbbr b);
+
+#define MAKE_FUNCTION_WITH_TWO_DEFINE(base, op, leftTypeAbbr, rightTypeAbbr, result) \
+ base^ MPEXPR_NAME::op(TYPE_FOR_ABBR_##leftTypeAbbr a, TYPE_FOR_ABBR_##rightTypeAbbr b) { return gcnew MPEXPR(result)(this, a, b); }
+
+//functions with one argument and simple result
+//#define MAKE_SIMPLE_FUNCTION_WITH_ONE(base, action, op, resultType, argType) \
+// MAKE_SIMPLE_FUNCTION_WITH_ONE_##action(base, op, resultType, Expr)
+//
+//#define MAKE_SIMPLE_FUNCTION_WITH_LIMB(base, action, op, resultType, argType) \
+// MAKE_SIMPLE_FUNCTION_WITH_ONE_##action(base, op, resultType, argType)
+//
+//#define MAKE_SIMPLE_FUNCTION_WITH_ONE_DECLARE(base, op, resultTypeAbbr, argTypeAbbr) \
+// TYPE_FOR_ABBR_##resultTypeAbbr op(TYPE_FOR_ABBR_##argTypeAbbr a);
+//
+//#define MAKE_SIMPLE_FUNCTION_WITH_ONE_DEFINE(base, op, resultTypeAbbr, argTypeAbbr) \
+// TYPE_FOR_ABBR_##resultTypeAbbr HugeInt::op(TYPE_FOR_ABBR_##argTypeAbbr a) { return gcnew LIT(MPTYPE_NAME)result##Expression(this, a); }
+
+//unary operators
+#define MAKE_UNARY_OPERATOR(base, action, op, result, mpType) \
+ MAKE_UNARY_OPERATOR_##action(base, op, result##mpType, Expr)
+
+#define MAKE_UNARY_OPERATOR_DECLARE(base, op, result, type) \
+ static base^ operator op(TYPE_FOR_ABBR_##type a);
+
+#define MAKE_UNARY_OPERATOR_DEFINE(base, op, result, type) \
+ base^ MPEXPR_NAME::operator op(TYPE_FOR_ABBR_##type a) { return gcnew MPEXPR(result)(a); }
+
+//binary operators
+#define MAKE_BINARY_OPERATOR_DECLARE(base, op, result, leftType, rightType, left, right) \
+ static base^ operator op(TYPE_FOR_ABBR_##leftType a, TYPE_FOR_ABBR_##rightType b);
+
+#define MAKE_BINARY_OPERATOR_DEFINE(base, op, result, leftType, rightType, left, right) \
+ base^ MPEXPR_NAME::operator op(TYPE_FOR_ABBR_##leftType a, TYPE_FOR_ABBR_##rightType b) { return gcnew MPEXPR(result)(left, right); }
+
+#define MAKE_BINARY_OPERATOR_STANDARD(base, action, op, result, leftType, rightType) \
+ MAKE_BINARY_OPERATOR_##action(base, op, result##leftType##rightType, Expr, Expr, a, b)
+
+#define MAKE_BINARY_OPERATOR_RLIMB(base, action, op, result, mpType, limbType) \
+ MAKE_BINARY_OPERATOR_##action(base, op, result##mpType##limbType, Expr, limbType, a, b)
+
+#define MAKE_BINARY_OPERATOR_LLIMB(base, action, op, result, mpType, limbType) \
+ MAKE_BINARY_OPERATOR_##action(base, op, result##limbType##mpType, limbType, Expr, a, b)
+
+#define MAKE_BINARY_OPERATOR_LLIMB_R(base, action, op, result, mpType, limbType) \
+ MAKE_BINARY_OPERATOR_##action(base, op, result##mpType##limbType, limbType, Expr, b, a)
+
+#pragma endregion
+
+#pragma region expression assignment macros
+
+#define DEFINE_ASSIGNMENT_PROLOG(name) void MPEXPR(name)::AssignTo(MP(ptr) destination)
+
+#define DEFINE_UNARY_ASSIGNMENT_REF(name, typeAbbr, operation) \
+ DEFINE_ASSIGNMENT_PROLOG(name##typeAbbr) \
+ { \
+ Operand->AssignTo(destination); \
+ operation(destination, destination); \
+ }
+
+#define DEFINE_UNARY_ASSIGNMENT_VAL(name, typeAbbr, operation) \
+ DEFINE_ASSIGNMENT_PROLOG(name##typeAbbr) \
+ { \
+ operation(destination, Operand); \
+ }
+
+#define DEFINE_BINARY_ASSIGNMENT_REF_REF(name, typeAbbr, operation) \
+ DEFINE_ASSIGNMENT_PROLOG(name##typeAbbr##typeAbbr) \
+ { \
+ IN_CONTEXT(Left, Right); \
+ operation(destination, CTXT(0), CTXT(1)); \
+ }
+
+#define DEFINE_BINARY_ASSIGNMENT_REF_VAL(name, leftTypeAbbr, rightTypeAbbr, operation) \
+ DEFINE_ASSIGNMENT_PROLOG(name##leftTypeAbbr##rightTypeAbbr) \
+ { \
+ Left->AssignTo(destination); \
+ operation(destination, destination, Right); \
+ }
+
+#define DEFINE_BINARY_ASSIGNMENT_VAL_REF(name, leftTypeAbbr, rightTypeAbbr, operation) \
+ DEFINE_ASSIGNMENT_PROLOG(name##leftTypeAbbr##rightTypeAbbr) \
+ { \
+ Right->AssignTo(destination); \
+ operation(destination, Left, destination); \
+ }
+
+#define DEFINE_BINARY_ASSIGNMENT_VAL_VAL(name, leftTypeAbbr, rightTypeAbbr, operation) \
+ DEFINE_ASSIGNMENT_PROLOG(name##leftTypeAbbr##rightTypeAbbr) \
+ { \
+ operation(destination, Left, Right); \
+ }
+
+#define DEFINE_BINARY_ASSIGNMENT_REF_SI(name, leftTypeAbbr, rightTypeAbbr, positiveOp, negativeOp) \
+ DEFINE_ASSIGNMENT_PROLOG(name##leftTypeAbbr##rightTypeAbbr) \
+ { \
+ Left->AssignTo(destination); \
+ if (Right >= 0) \
+ positiveOp(destination, destination, (mpir_ui)Right); \
+ else \
+ negativeOp(destination, destination, (mpir_ui)-Right); \
+ }
+
+#define DEFINE_BINARY_ASSIGNMENT_SI_REF(name, leftTypeAbbr, rightTypeAbbr, positiveOp, negativeOp1, negativeOp2) \
+ DEFINE_ASSIGNMENT_PROLOG(name##leftTypeAbbr##rightTypeAbbr) \
+ { \
+ Right->AssignTo(destination); \
+ if (Left >= 0) \
+ positiveOp(destination, (mpir_ui)Left, destination); \
+ else \
+ { \
+ negativeOp1(destination, destination, (mpir_ui)-Left); \
+ negativeOp2(destination, destination); \
+ } \
+ }
+
+#define DEFINE_TERNARY_ASSIGNMENT_REF_REF_REF(name, typeAbbr, operation) \
+ DEFINE_ASSIGNMENT_PROLOG(name##typeAbbr##typeAbbr##typeAbbr) \
+ { \
+ IN_CONTEXT(Left, Middle, Right); \
+ operation(destination, CTXT(0), CTXT(1), CTXT(2)); \
+ }
+
+#define DEFINE_TERNARY_ASSIGNMENT_REF_VAL_REF(name, leftT, middleT, rightT, operation) \
+ DEFINE_ASSIGNMENT_PROLOG(name##leftT##middleT##rightT) \
+ { \
+ IN_CONTEXT(Left, Right); \
+ operation(destination, CTXT(0), Middle, CTXT(1)); \
+ }
+
+#pragma endregion
diff --git a/mpir.net/mpir.net/HugeInt.cpp b/mpir.net/mpir.net/HugeInt.cpp
index fe3ddfdf..50fccefd 100644
--- a/mpir.net/mpir.net/HugeInt.cpp
+++ b/mpir.net/mpir.net/HugeInt.cpp
@@ -18,6 +18,7 @@ along with the MPIR Library. If not, see http://www.gnu.org/licenses/.
*/
#include "Stdafx.h"
+#include "HugeInt.h"
#include "Random.h"
using namespace System::Runtime::InteropServices;
@@ -30,38 +31,38 @@ namespace MPIR
void MpirSettings::ToStringDigits::set(int value)
{
_toStringDigits = value;
- _toStringModulo = gcnew HugeInt(HugeInt::Power(10, value));
+ _toStringModulo = gcnew MPTYPE(MPTYPE::Power(10, value));
}
#pragma endregion
#pragma region construction
- HugeInt::HugeInt()
+ MPTYPE::MPTYPE()
{
AllocateStruct();
- mpz_init(_value);
+ MP(init)(_value);
}
- HugeInt::HugeInt(IntegerExpression^ value)
+ MPTYPE::MPTYPE(MPEXPR_NAME^ value)
{
AllocateStruct();
- mpz_init(_value);
+ MP(init)(_value);
value->AssignTo(_value);
}
- HugeInt::HugeInt(mp_bitcnt_t bits)
+ MPTYPE::MPTYPE(mp_bitcnt_t bits)
{
AllocateStruct();
- mpz_init2(_value, bits);
+ MP(init2)(_value, bits);
}
- void HugeInt::FromString(String^ value, int base)
+ void MPTYPE::FromString(String^ value, int base)
{
AllocateStruct();
IntPtr ptr = Marshal::StringToHGlobalAnsi(value);
- bool success = 0 == mpz_init_set_str(_value, (char*)(void*)ptr, base);
+ bool success = 0 == MP(init_set_str)(_value, (char*)(void*)ptr, base);
Marshal::FreeHGlobal(ptr);
if(!success)
@@ -71,34 +72,34 @@ namespace MPIR
}
}
- void HugeInt::SetTo(String^ value, int base)
+ void MPTYPE::SetTo(String^ value, int base)
{
IntPtr ptr = Marshal::StringToHGlobalAnsi(value);
- bool success = 0 == mpz_set_str(_value, (char*)(void*)ptr, base);
+ bool success = 0 == MP(set_str)(_value, (char*)(void*)ptr, base);
Marshal::FreeHGlobal(ptr);
if(!success)
throw gcnew ArgumentException("Invalid number", "value");
}
- HugeInt^ HugeInt::FromLong(mpir_si value)
+ MPTYPE^ MPTYPE::FromLong(mpir_si value)
{
- auto result = gcnew HugeInt();
- mpz_set_si(result->_value, value);
+ auto result = gcnew MPTYPE();
+ MP(set_si)(result->_value, value);
return result;
}
- HugeInt^ HugeInt::FromUlong(mpir_ui value)
+ MPTYPE^ MPTYPE::FromUlong(mpir_ui value)
{
- auto result = gcnew HugeInt();
- mpz_set_ui(result->_value, value);
+ auto result = gcnew MPTYPE();
+ MP(set_ui)(result->_value, value);
return result;
}
- HugeInt^ HugeInt::FromDouble(double value)
+ MPTYPE^ MPTYPE::FromDouble(double value)
{
- auto result = gcnew HugeInt();
- mpz_set_d(result->_value, value);
+ auto result = gcnew MPTYPE();
+ MP(set_d)(result->_value, value);
return result;
}
@@ -106,7 +107,7 @@ namespace MPIR
#pragma region object overrides
- String^ HugeInt::ToString(int base, bool lowercase, int maxDigits)
+ String^ MPTYPE::ToString(int base, bool lowercase, int maxDigits)
{
size_t allocated;
bool negative = false;
@@ -123,7 +124,7 @@ namespace MPIR
else
{
AssignTo(context);
- allocated = mpz_sizeinbase(_value, base == 0 ? 10 : base) + 2;
+ allocated = MP(sizeinbase)(_value, base == 0 ? 10 : base) + 2;
}
char* allocatedStr = (char*)(*__gmp_allocate_func)(allocated);
@@ -138,23 +139,23 @@ namespace MPIR
*str++ = '.';
}
- mpz_get_str(str, (base <= 36 && !lowercase) ? -base : base, context.Args[0]);
+ MP(get_str)(str, (base <= 36 && !lowercase) ? -base : base, CTXT(0));
auto result = gcnew String(allocatedStr);
(*__gmp_free_func)(allocatedStr, allocated);
return result;
}
- int IntegerExpression::GetHashCode()
+ int MPEXPR_NAME::GetHashCode()
{
IN_CONTEXT(this);
mp_limb_t hash = 0;
- mp_limb_t* ptr = context.Args[0]->_mp_d;
- for(int i = abs(context.Args[0]->_mp_size); i > 0; i--)
+ mp_limb_t* ptr = CTXT(0)->_mp_d;
+ for(int i = abs(CTXT(0)->_mp_size); i > 0; i--)
hash ^= *ptr++;
- if(context.Args[0]->_mp_size < 0)
+ if(CTXT(0)->_mp_size < 0)
hash = (mp_limb_t)-(mpir_si)hash;
return hash.GetHashCode();
@@ -164,14 +165,14 @@ namespace MPIR
#pragma region Interface implementations
- int IntegerExpression::CompareTo(Object^ a, bool& valid)
+ int MPEXPR_NAME::CompareTo(Object^ a, bool& valid)
{
valid = true;
if (IS_NULL(a))
return 1;
- IntegerExpression^ expr = dynamic_cast(a);
+ MPEXPR_NAME^ expr = dynamic_cast(a);
if(!IS_NULL(expr))
return CompareTo(expr);
@@ -180,26 +181,26 @@ namespace MPIR
if(a->GetType() == mpir_ui::typeid)
{
AssignTo(context);
- return mpz_cmp_ui(context.Args[0], (mpir_ui)a);
+ return MP(cmp_ui)(CTXT(0), (mpir_ui)a);
}
if(a->GetType() == mpir_si::typeid)
{
AssignTo(context);
- return mpz_cmp_si(context.Args[0], (mpir_si)a);
+ return MP(cmp_si)(CTXT(0), (mpir_si)a);
}
if(a->GetType() == double::typeid)
{
AssignTo(context);
- return mpz_cmp_d(context.Args[0], (double)a);
+ return MP(cmp_d)(CTXT(0), (double)a);
}
valid = false;
return 0;
}
- int IntegerExpression::CompareTo(Object^ a)
+ int MPEXPR_NAME::CompareTo(Object^ a)
{
bool valid;
auto result = CompareTo(a, valid);
@@ -210,16 +211,16 @@ namespace MPIR
throw gcnew ArgumentException("Invalid argument type", "a");
}
- int IntegerExpression::CompareTo(IntegerExpression^ a)
+ int MPEXPR_NAME::CompareTo(MPEXPR_NAME^ a)
{
if (IS_NULL(a))
return 1;
IN_CONTEXT(this, a);
- return mpz_cmp(context.Args[0], context.Args[1]);
+ return MP(cmp)(CTXT(0), CTXT(1));
}
- bool IntegerExpression::Equals(Object^ a)
+ bool MPEXPR_NAME::Equals(Object^ a)
{
bool valid;
auto result = CompareTo(a, valid);
@@ -227,7 +228,7 @@ namespace MPIR
return valid && result == 0;
}
- bool IntegerExpression::Equals(IntegerExpression^ a)
+ bool MPEXPR_NAME::Equals(MPEXPR_NAME^ a)
{
return CompareTo(a) == 0;
}
@@ -236,31 +237,31 @@ namespace MPIR
#pragma region expression special cases
- void IntegerDivideExpression::custom_mpz_div(mpz_ptr q, mpz_srcptr n, mpz_srcptr d)
+ void MPEXPR(Divide)::CUSTOM_MP(div)(MP(ptr) q, MP(srcptr) n, MP(srcptr) d)
{
switch((rounding == RoundingModes::Default) ? MpirSettings::RoundingMode : rounding)
{
case RoundingModes::Floor:
IS_NULL(_remainder)
- ? mpz_fdiv_q(q, n, d)
- : mpz_fdiv_qr(q, _remainder->_value, n, d);
+ ? MP(fdiv_q)(q, n, d)
+ : MP(fdiv_qr)(q, _remainder->_value, n, d);
break;
case RoundingModes::Ceiling:
IS_NULL(_remainder)
- ? mpz_cdiv_q(q, n, d)
- : mpz_cdiv_qr(q, _remainder->_value, n, d);
+ ? MP(cdiv_q)(q, n, d)
+ : MP(cdiv_qr)(q, _remainder->_value, n, d);
break;
default:
IS_NULL(_remainder)
- ? mpz_tdiv_q(q, n, d)
- : mpz_tdiv_qr(q, _remainder->_value, n, d);
+ ? MP(tdiv_q)(q, n, d)
+ : MP(tdiv_qr)(q, _remainder->_value, n, d);
break;
}
}
- void IntegerDivideUiExpression::custom_mpz_div_ui(mpz_ptr q, mpz_srcptr n, mpir_ui d)
+ void MPEXPR(DivideUi)::CUSTOM_MP(div_ui)(MP(ptr) q, MP(srcptr) n, mpir_ui d)
{
mpir_ui limb;
@@ -268,20 +269,20 @@ namespace MPIR
{
case RoundingModes::Floor:
limb = IS_NULL(_remainder)
- ? mpz_fdiv_q_ui(q, n, d)
- : mpz_fdiv_qr_ui(q, _remainder->_value, n, d);
+ ? MP(fdiv_q_ui)(q, n, d)
+ : MP(fdiv_qr_ui)(q, _remainder->_value, n, d);
break;
case RoundingModes::Ceiling:
limb = IS_NULL(_remainder)
- ? mpz_cdiv_q_ui(q, n, d)
- : mpz_cdiv_qr_ui(q, _remainder->_value, n, d);
+ ? MP(cdiv_q_ui)(q, n, d)
+ : MP(cdiv_qr_ui)(q, _remainder->_value, n, d);
break;
default:
limb = IS_NULL(_remainder)
- ? mpz_tdiv_q_ui(q, n, d)
- : mpz_tdiv_qr_ui(q, _remainder->_value, n, d);
+ ? MP(tdiv_q_ui)(q, n, d)
+ : MP(tdiv_qr_ui)(q, _remainder->_value, n, d);
break;
}
@@ -289,55 +290,55 @@ namespace MPIR
_limbRemainder(limb);
}
- void IntegerShiftRightExpression::custom_mpz_div_2exp(mpz_ptr q, mpz_srcptr n, mp_bitcnt_t d)
+ void MPEXPR(ShiftRight)::CUSTOM_MP(div_2exp)(MP(ptr) q, MP(srcptr) n, mp_bitcnt_t d)
{
switch((rounding == RoundingModes::Default) ? MpirSettings::RoundingMode : rounding)
{
case RoundingModes::Floor:
_remainder
- ? mpz_fdiv_r_2exp(q, n, d)
- : mpz_fdiv_q_2exp(q, n, d);
+ ? MP(fdiv_r_2exp)(q, n, d)
+ : MP(fdiv_q_2exp)(q, n, d);
break;
case RoundingModes::Ceiling:
_remainder
- ? mpz_cdiv_r_2exp(q, n, d)
- : mpz_cdiv_q_2exp(q, n, d);
+ ? MP(cdiv_r_2exp)(q, n, d)
+ : MP(cdiv_q_2exp)(q, n, d);
break;
default:
_remainder
- ? mpz_tdiv_r_2exp(q, n, d)
- : mpz_tdiv_q_2exp(q, n, d);
+ ? MP(tdiv_r_2exp)(q, n, d)
+ : MP(tdiv_q_2exp)(q, n, d);
break;
}
}
- void IntegerModExpression::custom_mpz_mod(mpz_ptr r, mpz_srcptr n, mpz_srcptr d)
+ void MPEXPR(Mod)::CUSTOM_MP(mod)(MP(ptr) r, MP(srcptr) n, MP(srcptr) d)
{
switch((rounding == RoundingModes::Default) ? MpirSettings::RoundingMode : rounding)
{
case RoundingModes::Floor:
IS_NULL(_quotient)
- ? mpz_fdiv_r(r, n, d)
- : mpz_fdiv_qr(_quotient->_value, r, n, d);
+ ? MP(fdiv_r)(r, n, d)
+ : MP(fdiv_qr)(_quotient->_value, r, n, d);
break;
case RoundingModes::Ceiling:
IS_NULL(_quotient)
- ? mpz_cdiv_r(r, n, d)
- : mpz_cdiv_qr(_quotient->_value, r, n, d);
+ ? MP(cdiv_r)(r, n, d)
+ : MP(cdiv_qr)(_quotient->_value, r, n, d);
break;
default:
IS_NULL(_quotient)
- ? mpz_tdiv_r(r, n, d)
- : mpz_tdiv_qr(_quotient->_value, r, n, d);
+ ? MP(tdiv_r)(r, n, d)
+ : MP(tdiv_qr)(_quotient->_value, r, n, d);
break;
}
}
- void IntegerModUiExpression::custom_mpz_mod_ui(mpz_ptr r, mpz_srcptr n, mpir_ui d)
+ void MPEXPR(ModUi)::CUSTOM_MP(mod_ui)(MP(ptr) r, MP(srcptr) n, mpir_ui d)
{
mpir_ui limb;
@@ -345,20 +346,20 @@ namespace MPIR
{
case RoundingModes::Floor:
limb = IS_NULL(_quotient)
- ? mpz_fdiv_r_ui(r, n, d)
- : mpz_fdiv_qr_ui(_quotient->_value, r, n, d);
+ ? MP(fdiv_r_ui)(r, n, d)
+ : MP(fdiv_qr_ui)(_quotient->_value, r, n, d);
break;
case RoundingModes::Ceiling:
limb = IS_NULL(_quotient)
- ? mpz_cdiv_r_ui(r, n, d)
- : mpz_cdiv_qr_ui(_quotient->_value, r, n, d);
+ ? MP(cdiv_r_ui)(r, n, d)
+ : MP(cdiv_qr_ui)(_quotient->_value, r, n, d);
break;
default:
limb = IS_NULL(_quotient)
- ? mpz_tdiv_r_ui(r, n, d)
- : mpz_tdiv_qr_ui(_quotient->_value, r, n, d);
+ ? MP(tdiv_r_ui)(r, n, d)
+ : MP(tdiv_qr_ui)(_quotient->_value, r, n, d);
break;
}
@@ -366,41 +367,41 @@ namespace MPIR
_limbRemainder(limb);
}
- void IntegerRootExpression::custom_mpz_root(mpz_ptr dest, mpz_srcptr oper, mpir_ui power)
+ void MPEXPR(Root)::CUSTOM_MP(root)(MP(ptr) dest, MP(srcptr) oper, mpir_ui power)
{
if(!IS_NULL(_remainder))
- mpz_rootrem(dest, _remainder->_value, oper, power);
+ MP(rootrem)(dest, _remainder->_value, oper, power);
else if (IS_NULL(_exact))
- mpz_nthroot(dest, oper, power);
+ MP(nthroot)(dest, oper, power);
else
- _exact(mpz_root(dest, oper, power) != 0);
+ _exact(MP(root)(dest, oper, power) != 0);
}
- void IntegerSquareRootExpression::custom_mpz_sqrt(mpz_ptr dest, mpz_srcptr oper)
+ void MPEXPR(SquareRoot)::CUSTOM_MP(sqrt)(MP(ptr) dest, MP(srcptr) oper)
{
IS_NULL(_remainder)
- ? mpz_sqrt(dest, oper)
- : mpz_sqrtrem(dest, _remainder->_value, oper);
+ ? MP(sqrt)(dest, oper)
+ : MP(sqrtrem)(dest, _remainder->_value, oper);
}
- void IntegerGcdExpression::custom_mpz_gcd(mpz_ptr dest, mpz_srcptr a, mpz_srcptr b)
+ void MPEXPR(Gcd)::CUSTOM_MP(gcd)(MP(ptr) dest, MP(srcptr) a, MP(srcptr) b)
{
switch ((IS_NULL(_s) ? 0 : 1) + (IS_NULL(_t) ? 0 : 2))
{
case 0:
- mpz_gcd(dest, a, b);
+ MP(gcd)(dest, a, b);
break;
case 1:
- mpz_gcdext(dest, _s->_value, NULL, a, b);
+ MP(gcdext)(dest, _s->_value, NULL, a, b);
break;
case 2:
- mpz_gcdext(dest, _t->_value, NULL, b, a);
+ MP(gcdext)(dest, _t->_value, NULL, b, a);
break;
case 3:
- mpz_gcdext(dest, _s->_value, _t->_value, a, b);
+ MP(gcdext)(dest, _s->_value, _t->_value, a, b);
break;
}
}
@@ -409,67 +410,112 @@ namespace MPIR
#pragma region Arithmetic
- DEFINE_OPERATIONS(DEFINE)
+ MAKE_BINARY_OPERATOR_STANDARD (MPEXPR_NAME, DEFINE, +, Add, Int, Int)
+ MAKE_BINARY_OPERATOR_RLIMB (MPEXPR_NAME, DEFINE, +, Add, Int, Ui)
+ MAKE_BINARY_OPERATOR_LLIMB_R (MPEXPR_NAME, DEFINE, +, Add, Int, Ui)
+ MAKE_BINARY_OPERATOR_RLIMB (MPEXPR_NAME, DEFINE, +, Add, Int, Si)
+ MAKE_BINARY_OPERATOR_LLIMB_R (MPEXPR_NAME, DEFINE, +, Add, Int, Si)
+
+ MAKE_BINARY_OPERATOR_STANDARD (MPEXPR_NAME, DEFINE, -, Subtract, Int, Int)
+ MAKE_BINARY_OPERATOR_RLIMB (MPEXPR_NAME, DEFINE, -, Subtract, Int, Ui)
+ MAKE_BINARY_OPERATOR_LLIMB (MPEXPR_NAME, DEFINE, -, Subtract, Int, Ui)
+ MAKE_BINARY_OPERATOR_RLIMB (MPEXPR_NAME, DEFINE, -, Subtract, Int, Si)
+ MAKE_BINARY_OPERATOR_LLIMB (MPEXPR_NAME, DEFINE, -, Subtract, Int, Si)
+
+ MAKE_BINARY_OPERATOR_STANDARD (MPEXPR_NAME, DEFINE, *, Multiply, Int, Int)
+ MAKE_BINARY_OPERATOR_RLIMB (MPEXPR_NAME, DEFINE, *, Multiply, Int, Ui)
+ MAKE_BINARY_OPERATOR_LLIMB_R (MPEXPR_NAME, DEFINE, *, Multiply, Int, Ui)
+ MAKE_BINARY_OPERATOR_RLIMB (MPEXPR_NAME, DEFINE, *, Multiply, Int, Si)
+ MAKE_BINARY_OPERATOR_LLIMB_R (MPEXPR_NAME, DEFINE, *, Multiply, Int, Si)
+
+ MAKE_BINARY_OPERATOR_RLIMB (MPEXPR_NAME, DEFINE, <<, ShiftLeft, Int, Bits)
+ MAKE_BINARY_OPERATOR_RLIMB (MPEXPR(ShiftRight), DEFINE, >>, ShiftRight, Int, Bits)
+
+ MAKE_UNARY_OPERATOR (MPEXPR_NAME, DEFINE, -, Negate, Int)
+
+ MAKE_VOID_FUNCTION (MPEXPR_NAME, DEFINE, Abs, Int)
+
+ MAKE_BINARY_OPERATOR_STANDARD (MPEXPR(Divide), DEFINE, /, Divide, Int, Int)
+ MAKE_BINARY_OPERATOR_RLIMB (MPEXPR(DivideUi), DEFINE, /, Divide, Int, Ui)
+
+ MAKE_BINARY_OPERATOR_STANDARD (MPEXPR(Mod), DEFINE, %, Mod, Int, Int)
+ MAKE_BINARY_OPERATOR_RLIMB (MPEXPR(ModUi), DEFINE, %, Mod, Int, Ui)
+
+ MAKE_BINARY_OPERATOR_RLIMB (MPEXPR_NAME, DEFINE, ^, Power, Int, Ui)
+
+ MAKE_FUNCTION_WITH_ONE (MPEXPR_NAME, DEFINE, DivideExactly, Int)
+ MAKE_FUNCTION_WITH_LIMB (MPEXPR_NAME, DEFINE, DivideExactly, Ui)
+
+ MAKE_FUNCTION_WITH_TWO (MPEXPR_NAME, DEFINE, PowerMod, Int, Int)
+ MAKE_FUNCTION_WITH_TWO_LLIMB (MPEXPR_NAME, DEFINE, PowerMod, Ui, Int)
+
+ MAKE_FUNCTION_WITH_LIMB (MPEXPR(Root), DEFINE, Root, Ui)
+ MAKE_VOID_FUNCTION (MPEXPR(SquareRoot), DEFINE, SquareRoot, Int)
+
+ MAKE_BINARY_OPERATOR_STANDARD (MPEXPR_NAME, DEFINE, &, And, Int, Int)
+ MAKE_BINARY_OPERATOR_STANDARD (MPEXPR_NAME, DEFINE, |, Or, Int, Int)
+ MAKE_BINARY_OPERATOR_STANDARD (MPEXPR_NAME, DEFINE, ^, Xor, Int, Int)
+ MAKE_UNARY_OPERATOR (MPEXPR_NAME, DEFINE, ~, Complement, Int)
- DEFINE_UNARY_ASSIGNMENT_REF(Complement, Int, mpz_com)
- DEFINE_UNARY_ASSIGNMENT_REF(Negate, Int, mpz_neg)
- DEFINE_UNARY_ASSIGNMENT_REF(Abs, Int, mpz_abs)
+ DEFINE_UNARY_ASSIGNMENT_REF(Complement, Int, MP(com))
+ DEFINE_UNARY_ASSIGNMENT_REF(Negate, Int, MP(neg))
+ DEFINE_UNARY_ASSIGNMENT_REF(Abs, Int, MP(abs))
- DEFINE_BINARY_ASSIGNMENT_REF_REF(Add, Int, mpz_add)
- DEFINE_BINARY_ASSIGNMENT_REF_VAL(Add, Int, Ui, mpz_add_ui)
- DEFINE_BINARY_ASSIGNMENT_REF_SI (Add, Int, Si, mpz_add_ui, mpz_sub_ui)
+ DEFINE_BINARY_ASSIGNMENT_REF_REF(Add, Int, MP(add))
+ DEFINE_BINARY_ASSIGNMENT_REF_VAL(Add, Int, Ui, MP(add_ui))
+ DEFINE_BINARY_ASSIGNMENT_REF_SI (Add, Int, Si, MP(add_ui), MP(sub_ui))
- DEFINE_BINARY_ASSIGNMENT_REF_REF(Subtract, Int, mpz_sub)
- DEFINE_BINARY_ASSIGNMENT_REF_VAL(Subtract, Int, Ui, mpz_sub_ui)
- DEFINE_BINARY_ASSIGNMENT_VAL_REF(Subtract, Ui, Int, mpz_ui_sub)
- DEFINE_BINARY_ASSIGNMENT_REF_SI (Subtract, Int, Si, mpz_sub_ui, mpz_add_ui)
- DEFINE_BINARY_ASSIGNMENT_SI_REF (Subtract, Si, Int, mpz_ui_sub, mpz_add_ui, mpz_neg)
+ DEFINE_BINARY_ASSIGNMENT_REF_REF(Subtract, Int, MP(sub))
+ DEFINE_BINARY_ASSIGNMENT_REF_VAL(Subtract, Int, Ui, MP(sub_ui))
+ DEFINE_BINARY_ASSIGNMENT_VAL_REF(Subtract, Ui, Int, MP(ui_sub))
+ DEFINE_BINARY_ASSIGNMENT_REF_SI (Subtract, Int, Si, MP(sub_ui), MP(add_ui))
+ DEFINE_BINARY_ASSIGNMENT_SI_REF (Subtract, Si, Int, MP(ui_sub), MP(add_ui), MP(neg))
- DEFINE_BINARY_ASSIGNMENT_REF_REF(Multiply, Int, mpz_mul)
- DEFINE_BINARY_ASSIGNMENT_REF_VAL(Multiply, Int, Ui, mpz_mul_ui)
- DEFINE_BINARY_ASSIGNMENT_REF_VAL(Multiply, Int, Si, mpz_mul_si)
+ DEFINE_BINARY_ASSIGNMENT_REF_REF(Multiply, Int, MP(mul))
+ DEFINE_BINARY_ASSIGNMENT_REF_VAL(Multiply, Int, Ui, MP(mul_ui))
+ DEFINE_BINARY_ASSIGNMENT_REF_VAL(Multiply, Int, Si, MP(mul_si))
- DEFINE_BINARY_ASSIGNMENT_REF_REF(Divide, Int, custom_mpz_div)
- DEFINE_BINARY_ASSIGNMENT_REF_VAL(Divide, Int, Ui, custom_mpz_div_ui)
- DEFINE_BINARY_ASSIGNMENT_REF_REF(Mod, Int, custom_mpz_mod)
- DEFINE_BINARY_ASSIGNMENT_REF_VAL(Mod, Int, Ui, custom_mpz_mod_ui)
+ DEFINE_BINARY_ASSIGNMENT_REF_REF(Divide, Int, CUSTOM_MP(div))
+ DEFINE_BINARY_ASSIGNMENT_REF_VAL(Divide, Int, Ui, CUSTOM_MP(div_ui))
+ DEFINE_BINARY_ASSIGNMENT_REF_REF(Mod, Int, CUSTOM_MP(mod))
+ DEFINE_BINARY_ASSIGNMENT_REF_VAL(Mod, Int, Ui, CUSTOM_MP(mod_ui))
- DEFINE_BINARY_ASSIGNMENT_REF_VAL(ShiftLeft, Int, Bits, mpz_mul_2exp)
- DEFINE_BINARY_ASSIGNMENT_REF_VAL(ShiftRight, Int, Bits, custom_mpz_div_2exp)
+ DEFINE_BINARY_ASSIGNMENT_REF_VAL(ShiftLeft, Int, Bits, MP(mul_2exp))
+ DEFINE_BINARY_ASSIGNMENT_REF_VAL(ShiftRight, Int, Bits, CUSTOM_MP(div_2exp))
- DEFINE_BINARY_ASSIGNMENT_REF_REF(DivideExactly, Int, mpz_divexact)
- DEFINE_BINARY_ASSIGNMENT_REF_VAL(DivideExactly, Int, Ui, mpz_divexact_ui)
+ DEFINE_BINARY_ASSIGNMENT_REF_REF(DivideExactly, Int, MP(divexact))
+ DEFINE_BINARY_ASSIGNMENT_REF_VAL(DivideExactly, Int, Ui, MP(divexact_ui))
- DEFINE_BINARY_ASSIGNMENT_REF_VAL(Power, Int, Ui, mpz_pow_ui)
+ DEFINE_BINARY_ASSIGNMENT_REF_VAL(Power, Int, Ui, MP(pow_ui))
- DEFINE_BINARY_ASSIGNMENT_REF_VAL(Root, Int, Ui, custom_mpz_root)
- DEFINE_UNARY_ASSIGNMENT_REF (SquareRoot, Int, custom_mpz_sqrt)
+ DEFINE_BINARY_ASSIGNMENT_REF_VAL(Root, Int, Ui, CUSTOM_MP(root))
+ DEFINE_UNARY_ASSIGNMENT_REF (SquareRoot, Int, CUSTOM_MP(sqrt))
- DEFINE_BINARY_ASSIGNMENT_REF_REF(And, Int, mpz_and)
- DEFINE_BINARY_ASSIGNMENT_REF_REF(Or, Int, mpz_ior)
- DEFINE_BINARY_ASSIGNMENT_REF_REF(Xor, Int, mpz_xor)
+ DEFINE_BINARY_ASSIGNMENT_REF_REF(And, Int, MP(and))
+ DEFINE_BINARY_ASSIGNMENT_REF_REF(Or, Int, MP(ior))
+ DEFINE_BINARY_ASSIGNMENT_REF_REF(Xor, Int, MP(xor))
- DEFINE_BINARY_ASSIGNMENT_REF_REF(Gcd, Int, custom_mpz_gcd)
- DEFINE_BINARY_ASSIGNMENT_REF_REF(Lcm, Int, mpz_lcm)
- DEFINE_BINARY_ASSIGNMENT_REF_VAL(Lcm, Int, Ui, mpz_lcm_ui)
+ DEFINE_BINARY_ASSIGNMENT_REF_REF(Gcd, Int, CUSTOM_MP(gcd))
+ DEFINE_BINARY_ASSIGNMENT_REF_REF(Lcm, Int, MP(lcm))
+ DEFINE_BINARY_ASSIGNMENT_REF_VAL(Lcm, Int, Ui, MP(lcm_ui))
- DEFINE_TERNARY_ASSIGNMENT_REF_REF_REF(PowerMod, Int, mpz_powm);
- DEFINE_TERNARY_ASSIGNMENT_REF_VAL_REF(PowerMod, Int, Ui, Int, mpz_powm_ui)
+ DEFINE_TERNARY_ASSIGNMENT_REF_REF_REF(PowerMod, Int, MP(powm));
+ DEFINE_TERNARY_ASSIGNMENT_REF_VAL_REF(PowerMod, Int, Ui, Int, MP(powm_ui))
- mpir_ui IntegerExpression::Mod(mpir_ui d, RoundingModes rounding)
+ mpir_ui MPEXPR_NAME::Mod(mpir_ui d, RoundingModes rounding)
{
IN_CONTEXT(this);
switch((rounding == RoundingModes::Default) ? MpirSettings::RoundingMode : rounding)
{
case RoundingModes::Floor:
- return mpz_fdiv_ui(context.Args[0], d);
+ return MP(fdiv_ui)(CTXT(0), d);
case RoundingModes::Ceiling:
- return mpz_cdiv_ui(context.Args[0], d);
+ return MP(cdiv_ui)(CTXT(0), d);
default:
- return mpz_tdiv_ui(context.Args[0], d);
+ return MP(tdiv_ui)(CTXT(0), d);
}
}
@@ -479,10 +525,10 @@ namespace MPIR
#define chunkSize 1024
- size_t HugeInt::Write(Stream^ stream)
+ size_t MPTYPE::Write(Stream^ stream)
{
mpir_out_struct out;
- mpz_out_raw_m(out, _value);
+ MP(out_raw_m)(out, _value);
auto buffer = gcnew array(chunkSize);
auto ptr = out->written;
@@ -502,7 +548,7 @@ namespace MPIR
return out->writtenSize;
}
- size_t HugeInt::Read(Stream^ stream)
+ size_t MPTYPE::Read(Stream^ stream)
{
unsigned char csize_bytes[4];
mpir_out_struct out;
@@ -517,7 +563,7 @@ namespace MPIR
csize_bytes[i] = byte;
}
- mpz_inp_raw_p(_value, csize_bytes, out);
+ MP(inp_raw_p)(_value, csize_bytes, out);
if(out->writtenSize != 0)
{
@@ -536,20 +582,20 @@ namespace MPIR
toRead -= len;
}
- mpz_inp_raw_m(_value, out);
+ MP(inp_raw_m)(_value, out);
}
return 4 + out->writtenSize;
}
- size_t HugeInt::Write(TextWriter^ writer, int base, bool lowercase)
+ size_t MPTYPE::Write(TextWriter^ writer, int base, bool lowercase)
{
auto str = ToString(base, lowercase);
writer->Write(str);
return str->Length;
}
- size_t HugeInt::Read(TextReader^ reader, int base)
+ size_t MPTYPE::Read(TextReader^ reader, int base)
{
int c;
size_t nread = 0;
@@ -570,7 +616,7 @@ namespace MPIR
nread++;
// adapted from inp_str, which is shared by mpq_inp_str
- size_t HugeInt::ReadNoWhite(TextReader^ reader, int base, size_t nread)
+ size_t MPTYPE::ReadNoWhite(TextReader^ reader, int base, size_t nread)
{
char *str;
size_t alloc_size, str_size;
@@ -660,7 +706,7 @@ namespace MPIR
xsize = (((mp_size_t)
(str_size / __mp_bases[base].chars_per_bit_exactly))
/ GMP_NUMB_BITS + 2);
- MPZ_REALLOC (_value, xsize);
+ MP(realloc) (_value, xsize);
// Convert the byte array in base BASE to our bignum format.
xsize = mpn_set_str (_value->_mp_d, (unsigned char *) str, str_size, base);
@@ -674,80 +720,80 @@ namespace MPIR
#pragma region number-theoretic
- bool HugeInt::IsProbablePrime(MpirRandom^ random, int probability, mpir_ui pretested)
+ bool MPTYPE::IsProbablePrime(MpirRandom^ random, int probability, mpir_ui pretested)
{
- return mpz_probable_prime_p(_value, random->_value, probability, pretested) != 0;
+ return MP(probable_prime_p)(_value, random->_value, probability, pretested) != 0;
}
- bool HugeInt::IsLikelyPrime(MpirRandom^ random, mpir_ui pretested)
+ bool MPTYPE::IsLikelyPrime(MpirRandom^ random, mpir_ui pretested)
{
- return mpz_likely_prime_p(_value, random->_value, pretested) != 0;
+ return MP(likely_prime_p)(_value, random->_value, pretested) != 0;
}
- MAKE_FUNCTION_WITH_LIMB (IntegerExpression, DEFINE, NextPrimeCandidate, Rnd)
+ MAKE_FUNCTION_WITH_LIMB (MPEXPR_NAME, DEFINE, NextPrimeCandidate, Rnd)
DEFINE_ASSIGNMENT_PROLOG(NextPrimeCandidateIntRnd)
{
IN_CONTEXT(Left);
- mpz_next_prime_candidate(destination, context.Args[0], Right->_value);
+ MP(next_prime_candidate)(destination, CTXT(0), Right->_value);
}
- MAKE_FUNCTION_WITH_ONE (IntegerGcdExpression, DEFINE, Gcd, Int)
- MAKE_FUNCTION_WITH_ONE (IntegerExpression, DEFINE, Lcm, Int)
- MAKE_FUNCTION_WITH_LIMB (IntegerExpression, DEFINE, Lcm, Ui)
+ MAKE_FUNCTION_WITH_ONE (MPEXPR(Gcd), DEFINE, Gcd, Int)
+ MAKE_FUNCTION_WITH_ONE (MPEXPR_NAME, DEFINE, Lcm, Int)
+ MAKE_FUNCTION_WITH_LIMB (MPEXPR_NAME, DEFINE, Lcm, Ui)
- MAKE_FUNCTION_WITH_ONE (IntegerExpression, DEFINE, Invert, Int)
+ MAKE_FUNCTION_WITH_ONE (MPEXPR_NAME, DEFINE, Invert, Int)
DEFINE_ASSIGNMENT_PROLOG(InvertIntInt)
{
IN_CONTEXT(Left, Right);
- if (mpz_invert(destination, context.Args[0], context.Args[1]) == 0)
+ if (MP(invert)(destination, CTXT(0), CTXT(1)) == 0)
throw gcnew ArgumentException("Inverse does not exist");
}
- MAKE_FUNCTION_WITH_ONE (IntegerRemoveFactorsExpression, DEFINE, RemoveFactors, Int)
+ MAKE_FUNCTION_WITH_ONE (MPEXPR(RemoveFactors), DEFINE, RemoveFactors, Int)
DEFINE_ASSIGNMENT_PROLOG(RemoveFactorsIntInt)
{
IN_CONTEXT(Left, Right);
- auto result = mpz_remove(destination, context.Args[0], context.Args[1]);
+ auto result = MP(remove)(destination, CTXT(0), CTXT(1));
if(!IS_NULL(_count))
_count(result);
}
- DEFINE_BINARY_ASSIGNMENT_VAL_VAL(Power, Ui, Ui, mpz_ui_pow_ui)
+ DEFINE_BINARY_ASSIGNMENT_VAL_VAL(Power, Ui, Ui, MP(ui_pow_ui))
DEFINE_ASSIGNMENT_PROLOG(FactorialUiUi)
{
switch (Right)
{
case 1:
- mpz_fac_ui(destination, Left);
+ MP(fac_ui)(destination, Left);
break;
case 2:
- mpz_2fac_ui(destination, Left);
+ MP(2fac_ui)(destination, Left);
break;
default:
- mpz_mfac_uiui(destination, Left, Right);
+ MP(mfac_uiui)(destination, Left, Right);
break;
}
}
- DEFINE_UNARY_ASSIGNMENT_VAL(Primorial, Ui, mpz_primorial_ui)
- DEFINE_BINARY_ASSIGNMENT_VAL_VAL(Binomial, Ui, Ui, mpz_bin_uiui)
- DEFINE_BINARY_ASSIGNMENT_REF_VAL(Binomial, Int, Ui, mpz_bin_ui)
+ DEFINE_UNARY_ASSIGNMENT_VAL(Primorial, Ui, MP(primorial_ui))
+ DEFINE_BINARY_ASSIGNMENT_VAL_VAL(Binomial, Ui, Ui, MP(bin_uiui))
+ DEFINE_BINARY_ASSIGNMENT_REF_VAL(Binomial, Int, Ui, MP(bin_ui))
DEFINE_ASSIGNMENT_PROLOG(FibonacciUi)
{
IS_NULL(_previous)
- ? mpz_fib_ui(destination, Operand)
- : mpz_fib2_ui(destination, _previous->_value, Operand);
+ ? MP(fib_ui)(destination, Operand)
+ : MP(fib2_ui)(destination, _previous->_value, Operand);
}
DEFINE_ASSIGNMENT_PROLOG(LucasUi)
{
IS_NULL(_previous)
- ? mpz_lucnum_ui(destination, Operand)
- : mpz_lucnum2_ui(destination, _previous->_value, Operand);
+ ? MP(lucnum_ui)(destination, Operand)
+ : MP(lucnum2_ui)(destination, _previous->_value, Operand);
}
#pragma endregion
diff --git a/mpir.net/mpir.net/HugeInt.h b/mpir.net/mpir.net/HugeInt.h
index 69f84b04..678ab457 100644
--- a/mpir.net/mpir.net/HugeInt.h
+++ b/mpir.net/mpir.net/HugeInt.h
@@ -23,309 +23,43 @@ using namespace System;
using namespace System::IO;
using namespace System::Runtime::InteropServices;
-#pragma region misc macros
-
-#define IS_NULL(a) (Object::ReferenceEquals(a, nullptr))
-#define PIN(x) pin_ptr pinptr##x = &x[0]; void* pinned_##x = pinptr##x;
-
-#pragma endregion
-
-#pragma region Expression macros
-
-//defines a unary expression class
-#define DEFINE_UNARY_EXPRESSION(base, name, type) \
-private ref class Mpir##name##Expression : base \
-{ \
- internal: \
- type Operand; \
- virtual void AssignTo(mpz_ptr destination) override; \
- Mpir##name##Expression(type operand) \
- { \
- Operand = operand; \
- } \
-};
-
-//defines a binary expression class
-#define DEFINE_BINARY_EXPRESSION(base, name, leftType, rightType) \
-private ref class Mpir##name##Expression : base \
-{ \
- internal: \
- leftType Left; \
- rightType Right; \
- virtual void AssignTo(mpz_ptr destination) override; \
- Mpir##name##Expression(leftType left, rightType right) \
- { \
- Left = left; \
- Right = right; \
- } \
-};
-
-//defines a ternary expression class
-#define DEFINE_TERNARY_EXPRESSION(base, name, leftType, middleType, rightType) \
-private ref class Mpir##name##Expression : base \
-{ \
- internal: \
- leftType Left; \
- middleType Middle; \
- rightType Right; \
- virtual void AssignTo(mpz_ptr destination) override; \
- Mpir##name##Expression(leftType left, middleType middle, rightType right) \
- { \
- Left = left; \
- Middle = middle; \
- Right = right; \
- } \
-};
-
-#define IN_CONTEXT_1(a) \
- EvaluationContext context; \
- a->AssignTo(context)
-
-#define IN_CONTEXT_2(a, b) \
- EvaluationContext context; \
- a->AssignTo(context); \
- b->AssignTo(context)
-
-#define IN_CONTEXT_3(a, b, c) \
- EvaluationContext context; \
- a->AssignTo(context); \
- b->AssignTo(context); \
- c->AssignTo(context)
-
-#define COUNT_ARGS_IMPL2(_1, _2, _3, name, ...) name
-#define COUNT_ARGS_IMPL(args) COUNT_ARGS_IMPL2 args
-#define COUNT_ARGS(...) COUNT_ARGS_IMPL((__VA_ARGS__, 3, 2, 1))
-#define MACRO_CHOOSE2(prefix, number) prefix##number
-#define MACRO_CHOOSE1(prefix, number) MACRO_CHOOSE2(prefix, number)
-#define MACRO_CHOOSE(prefix, number) MACRO_CHOOSE1(prefix, number)
-#define MACRO_GLUE(x, y) x y
-#define IN_CONTEXT(...) MACRO_GLUE(MACRO_CHOOSE(IN_CONTEXT_, COUNT_ARGS(__VA_ARGS__)), (__VA_ARGS__))
-
-#define TYPE_FOR_ABBR_Int HugeInt^
-#define TYPE_FOR_ABBR_Expr IntegerExpression^
-#define TYPE_FOR_ABBR_Si mpir_si
-#define TYPE_FOR_ABBR_Ui mpir_ui
-#define TYPE_FOR_ABBR_Bits mp_bitcnt_t
-#define TYPE_FOR_ABBR_Rnd MpirRandom^
-
-//unary expressions
-#define DEFINE_UNARY_EXPRESSION_WITH_ONE(base, name, typeAbbr) \
- DEFINE_UNARY_EXPRESSION(base, name##typeAbbr, IntegerExpression^)
-
-#define DEFINE_UNARY_EXPRESSION_WITH_BUILT_INS_ONLY(base, name, typeAbbr) \
- DEFINE_UNARY_EXPRESSION(base, name##typeAbbr, TYPE_FOR_ABBR_##typeAbbr)
-
-//binary expressions
-#define DEFINE_BINARY_EXPRESSION_WITH_BUILT_INS_ONLY(base, name, leftTypeAbbr, rightTypeAbbr) \
- DEFINE_BINARY_EXPRESSION(base, name##leftTypeAbbr##rightTypeAbbr, TYPE_FOR_ABBR_##leftTypeAbbr, TYPE_FOR_ABBR_##rightTypeAbbr)
-
-#define DEFINE_BINARY_EXPRESSION_WITH_TWO(base, name, typeAbbr) \
- DEFINE_BINARY_EXPRESSION(base, name##typeAbbr##typeAbbr, IntegerExpression^, IntegerExpression^)
-
-#define DEFINE_BINARY_EXPRESSION_WITH_BUILT_IN_RIGHT(base, name, leftTypeAbbr, rightTypeAbbr) \
- DEFINE_BINARY_EXPRESSION(base, name##leftTypeAbbr##rightTypeAbbr, IntegerExpression^, TYPE_FOR_ABBR_##rightTypeAbbr)
-
-#define DEFINE_BINARY_EXPRESSION_WITH_BUILT_IN_LEFT(base, name, leftTypeAbbr, rightTypeAbbr) \
- DEFINE_BINARY_EXPRESSION(base, name##leftTypeAbbr##rightTypeAbbr, TYPE_FOR_ABBR_##leftTypeAbbr, IntegerExpression^)
-
-//ternary expressions
-#define DEFINE_TERNARY_EXPRESSION_WITH_THREE(base, name, typeAbbr) \
- DEFINE_TERNARY_EXPRESSION(base, name##typeAbbr##typeAbbr##typeAbbr, IntegerExpression^, IntegerExpression^, IntegerExpression^)
-
-#define DEFINE_TERNARY_EXPRESSION_WITH_BUILT_IN_MIDDLE(base, name, leftTypeAbbr, middleTypeAbbr, rightTypeAbbr) \
- DEFINE_TERNARY_EXPRESSION(base, name##leftTypeAbbr##middleTypeAbbr##rightTypeAbbr, IntegerExpression^, TYPE_FOR_ABBR_##middleTypeAbbr, IntegerExpression^)
-
-#pragma endregion
-
-#pragma region Method macros
-
-//void functions
-#define MAKE_VOID_FUNCTION(base, action, op, type) \
- MAKE_VOID_FUNCTION_##action(base, op, op##type)
-
-#define MAKE_VOID_FUNCTION_DECLARE(base, op, result) \
- base^ op();
-
-#define MAKE_VOID_FUNCTION_DEFINE(base, op, result) \
- base^ IntegerExpression::op() { return gcnew Mpir##result##Expression(this); }
-
-//one-arg functions
-#define MAKE_FUNCTION_WITH_ONE(base, action, op, argTypeAbbr) \
- MAKE_FUNCTION_WITH_ONE_##action(base, op, Expr, op##Int##argTypeAbbr)
-
-#define MAKE_FUNCTION_WITH_LIMB(base, action, op, argTypeAbbr) \
- MAKE_FUNCTION_WITH_ONE_##action(base, op, argTypeAbbr, op##Int##argTypeAbbr)
-
-#define MAKE_FUNCTION_WITH_ONE_DECLARE(base, op, argTypeAbbr, result) \
- base^ op(TYPE_FOR_ABBR_##argTypeAbbr a);
-
-#define MAKE_FUNCTION_WITH_ONE_DEFINE(base, op, argTypeAbbr, result) \
- base^ IntegerExpression::op(TYPE_FOR_ABBR_##argTypeAbbr a) { return gcnew Mpir##result##Expression(this, a); }
-
-//two-arg functions
-#define MAKE_FUNCTION_WITH_TWO(base, action, op, leftTypeAbbr, rightTypeAbbr) \
- MAKE_FUNCTION_WITH_TWO_##action(base, op, Expr, Expr, op##Int##leftTypeAbbr##rightTypeAbbr)
-
-#define MAKE_FUNCTION_WITH_TWO_LLIMB(base, action, op, leftTypeAbbr, rightTypeAbbr) \
- MAKE_FUNCTION_WITH_TWO_##action(base, op, leftTypeAbbr, Expr, op##Int##leftTypeAbbr##rightTypeAbbr)
-
-#define MAKE_FUNCTION_WITH_TWO_DECLARE(base, op, leftTypeAbbr, rightTypeAbbr, result) \
- base^ op(TYPE_FOR_ABBR_##leftTypeAbbr a, TYPE_FOR_ABBR_##rightTypeAbbr b);
-
-#define MAKE_FUNCTION_WITH_TWO_DEFINE(base, op, leftTypeAbbr, rightTypeAbbr, result) \
- base^ IntegerExpression::op(TYPE_FOR_ABBR_##leftTypeAbbr a, TYPE_FOR_ABBR_##rightTypeAbbr b) { return gcnew Mpir##result##Expression(this, a, b); }
-
-//functions with one argument and simple result
-//#define MAKE_SIMPLE_FUNCTION_WITH_ONE(base, action, op, resultType, argType) \
-// MAKE_SIMPLE_FUNCTION_WITH_ONE_##action(base, op, resultType, Expr)
-//
-//#define MAKE_SIMPLE_FUNCTION_WITH_LIMB(base, action, op, resultType, argType) \
-// MAKE_SIMPLE_FUNCTION_WITH_ONE_##action(base, op, resultType, argType)
-//
-//#define MAKE_SIMPLE_FUNCTION_WITH_ONE_DECLARE(base, op, resultTypeAbbr, argTypeAbbr) \
-// TYPE_FOR_ABBR_##resultTypeAbbr op(TYPE_FOR_ABBR_##argTypeAbbr a);
-//
-//#define MAKE_SIMPLE_FUNCTION_WITH_ONE_DEFINE(base, op, resultTypeAbbr, argTypeAbbr) \
-// TYPE_FOR_ABBR_##resultTypeAbbr HugeInt::op(TYPE_FOR_ABBR_##argTypeAbbr a) { return gcnew Mpir##result##Expression(this, a); }
-
-//unary operators
-#define MAKE_UNARY_OPERATOR(base, action, op, result, mpType) \
- MAKE_UNARY_OPERATOR_##action(base, op, result##mpType, Expr)
-
-#define MAKE_UNARY_OPERATOR_DECLARE(base, op, result, type) \
- static base^ operator op(TYPE_FOR_ABBR_##type a);
-
-#define MAKE_UNARY_OPERATOR_DEFINE(base, op, result, type) \
- base^ IntegerExpression::operator op(TYPE_FOR_ABBR_##type a) { return gcnew Mpir##result##Expression(a); }
-
-//binary operators
-#define MAKE_BINARY_OPERATOR_DECLARE(base, op, result, leftType, rightType, left, right) \
- static base^ operator op(TYPE_FOR_ABBR_##leftType a, TYPE_FOR_ABBR_##rightType b);
-
-#define MAKE_BINARY_OPERATOR_DEFINE(base, op, result, leftType, rightType, left, right) \
- base^ IntegerExpression::operator op(TYPE_FOR_ABBR_##leftType a, TYPE_FOR_ABBR_##rightType b) { return gcnew Mpir##result##Expression(left, right); }
-
-#define MAKE_BINARY_OPERATOR_STANDARD(base, action, op, result, leftType, rightType) \
- MAKE_BINARY_OPERATOR_##action(base, op, result##leftType##rightType, Expr, Expr, a, b)
-
-#define MAKE_BINARY_OPERATOR_RLIMB(base, action, op, result, mpType, limbType) \
- MAKE_BINARY_OPERATOR_##action(base, op, result##mpType##limbType, Expr, limbType, a, b)
-
-#define MAKE_BINARY_OPERATOR_LLIMB(base, action, op, result, mpType, limbType) \
- MAKE_BINARY_OPERATOR_##action(base, op, result##limbType##mpType, limbType, Expr, a, b)
-
-#define MAKE_BINARY_OPERATOR_LLIMB_R(base, action, op, result, mpType, limbType) \
- MAKE_BINARY_OPERATOR_##action(base, op, result##mpType##limbType, limbType, Expr, b, a)
-
-//master operators/functions definition
-#define DEFINE_OPERATIONS(action) \
- MAKE_BINARY_OPERATOR_STANDARD (IntegerExpression, action, +, Add, Int, Int) \
- MAKE_BINARY_OPERATOR_RLIMB (IntegerExpression, action, +, Add, Int, Ui) \
- MAKE_BINARY_OPERATOR_LLIMB_R (IntegerExpression, action, +, Add, Int, Ui) \
- MAKE_BINARY_OPERATOR_RLIMB (IntegerExpression, action, +, Add, Int, Si) \
- MAKE_BINARY_OPERATOR_LLIMB_R (IntegerExpression, action, +, Add, Int, Si) \
- \
- MAKE_BINARY_OPERATOR_STANDARD (IntegerExpression, action, -, Subtract, Int, Int) \
- MAKE_BINARY_OPERATOR_RLIMB (IntegerExpression, action, -, Subtract, Int, Ui) \
- MAKE_BINARY_OPERATOR_LLIMB (IntegerExpression, action, -, Subtract, Int, Ui) \
- MAKE_BINARY_OPERATOR_RLIMB (IntegerExpression, action, -, Subtract, Int, Si) \
- MAKE_BINARY_OPERATOR_LLIMB (IntegerExpression, action, -, Subtract, Int, Si) \
- \
- MAKE_BINARY_OPERATOR_STANDARD (IntegerExpression, action, *, Multiply, Int, Int) \
- MAKE_BINARY_OPERATOR_RLIMB (IntegerExpression, action, *, Multiply, Int, Ui) \
- MAKE_BINARY_OPERATOR_LLIMB_R (IntegerExpression, action, *, Multiply, Int, Ui) \
- MAKE_BINARY_OPERATOR_RLIMB (IntegerExpression, action, *, Multiply, Int, Si) \
- MAKE_BINARY_OPERATOR_LLIMB_R (IntegerExpression, action, *, Multiply, Int, Si) \
- \
- MAKE_BINARY_OPERATOR_RLIMB (IntegerExpression, action, <<, ShiftLeft, Int, Bits) \
- MAKE_BINARY_OPERATOR_RLIMB (IntegerShiftRightExpression, action, >>, ShiftRight, Int, Bits) \
- \
- MAKE_UNARY_OPERATOR (IntegerExpression, action, -, Negate, Int) \
- \
- MAKE_VOID_FUNCTION (IntegerExpression, action, Abs, Int) \
- \
- MAKE_BINARY_OPERATOR_STANDARD (IntegerDivideExpression, action, /, Divide, Int, Int) \
- MAKE_BINARY_OPERATOR_RLIMB (IntegerDivideUiExpression, action, /, Divide, Int, Ui) \
- \
- MAKE_BINARY_OPERATOR_STANDARD (IntegerModExpression, action, %, Mod, Int, Int) \
- MAKE_BINARY_OPERATOR_RLIMB (IntegerModUiExpression, action, %, Mod, Int, Ui) \
- \
- MAKE_BINARY_OPERATOR_RLIMB (IntegerExpression, action, ^, Power, Int, Ui) \
- \
- MAKE_FUNCTION_WITH_ONE (IntegerExpression, action, DivideExactly, Int) \
- MAKE_FUNCTION_WITH_LIMB (IntegerExpression, action, DivideExactly, Ui) \
- \
- MAKE_FUNCTION_WITH_TWO (IntegerExpression, action, PowerMod, Int, Int) \
- MAKE_FUNCTION_WITH_TWO_LLIMB (IntegerExpression, action, PowerMod, Ui, Int) \
- \
- MAKE_FUNCTION_WITH_LIMB (IntegerRootExpression, action, Root, Ui) \
- MAKE_VOID_FUNCTION (IntegerSquareRootExpression, action, SquareRoot, Int) \
- \
- MAKE_BINARY_OPERATOR_STANDARD (IntegerExpression, action, &, And, Int, Int) \
- MAKE_BINARY_OPERATOR_STANDARD (IntegerExpression, action, |, Or, Int, Int) \
- MAKE_BINARY_OPERATOR_STANDARD (IntegerExpression, action, ^, Xor, Int, Int) \
- MAKE_UNARY_OPERATOR (IntegerExpression, action, ~, Complement, Int) \
-
-#pragma endregion
+#ifdef SPECIALIZE_EXPRESSIONS
+#undef SPECIALIZE_EXPRESSIONS
+#undef MP
+#undef CUSTOM_MP
+#undef MPSTRUCT
+#undef MPTYPE
+#undef MPTYPE_NAME
+#undef MPEXPR_NAME
+#undef MPEXPR
+#undef CTXT
+#endif
+#define SPECIALIZE_EXPRESSIONS
+#define CUSTOM_MP(x) custom_mpz_##x
+#define MPSTRUCT __mpz_struct
+#define MP(x) mpz_##x
+#define MPTYPE HugeInt
+#define MPTYPE_NAME Integer
+#define MPEXPR_NAME LIT(MPTYPE_NAME)Expression
+#define MPEXPR(x) LIT(MPTYPE_NAME)##x##Expression
+#define CTXT(x) context.IntArgs[x]
+#include "ExpressionMacros.h"
namespace MPIR
{
ref class MpirRandom;
- ref class HugeInt;
- ref class IntegerDivideExpression;
- ref class IntegerDivideUiExpression;
- ref class IntegerModExpression;
- ref class IntegerDivModExpression;
- ref class IntegerModUiExpression;
- ref class IntegerShiftRightExpression;
- ref class IntegerRootExpression;
- ref class IntegerSquareRootExpression;
- ref class IntegerGcdExpression;
- ref class IntegerRemoveFactorsExpression;
- ref class IntegerSequenceExpression;
-
- #pragma region enums
-
- ///
- /// This enum defines the rounding modes MPIR supports. Division and modulo operations take an optional rounding mode parameter, or use the default, which is set in the static MpirSettings class.
- ///
- public enum class RoundingModes
- {
- /// Rounding mode is unspecified. Use a higher level default if available, fall back to Truncate.
- Default,
- /// Truncate. Quotient is rounded toward zero, and remainder has the same sign as the source number.
- Truncate,
- /// Round up. Quotient is rounded toward +infinity, and remainder has the opposite sign to the divisor.
- Ceiling,
- /// Round down. Quotient is rounded toward -infinity, and remainder has the sames sign as the divisor.
- Floor,
- };
-
- ///
- /// This enum defines the limb order used when importing or exporting a number.
- ///
- public enum class LimbOrder : __int8
- {
- /// Most significant limb comes first.
- MostSignificantFirst = 1,
- /// Least significant limb comes first.
- LeastSignificantFirst = -1,
- };
-
- ///
- /// This enum defines the byte order within each limb when importing or exporting a number.
- ///
- public enum class Endianness : __int8
- {
- /// The native byte order of the CPU is used.
- Native = 0,
- /// Most significant byte comes first in a limb.
- BigEndian = 1,
- /// Least significant byte comes first in a limb.
- LittleEndian = -1,
- };
-
- #pragma endregion
+ ref class MPTYPE;
+ ref class MPEXPR(Divide);
+ ref class MPEXPR(DivideUi);
+ ref class MPEXPR(Mod);
+ ref class MPEXPR(DivMod);
+ ref class MPEXPR(ModUi);
+ ref class MPEXPR(ShiftRight);
+ ref class MPEXPR(Root);
+ ref class MPEXPR(SquareRoot);
+ ref class MPEXPR(Gcd);
+ ref class MPEXPR(RemoveFactors);
+ ref class MPEXPR(Sequence);
#pragma region IntegerExpression
@@ -335,17 +69,17 @@ namespace MPIR
/// when they are either assigned to the Value property of an MPIR object, or are consumed by a function or operator that returns a primitive type.
/// Assignment to the Value property is necessary because .Net does not support overloading the assignment operator.
///
- public ref class IntegerExpression abstract : public IComparable, IComparable, IEquatable
+ public ref class MPEXPR_NAME abstract : public IComparable, IComparable, IEquatable
{
internal:
- IntegerExpression() { }
- virtual void AssignTo(mpz_ptr destination) abstract;
- virtual void AssignTo(EvaluationContext& destination)
+ MPEXPR_NAME() { }
+ virtual void AssignTo(MP(ptr) destination) abstract;
+ virtual void AssignTo(EvaluationContext& context)
{
- destination.Options = (EvaluationOptions) (destination.Options | (1 << destination.Index));
- auto ptr = &destination.Temp[destination.Index];
- destination.Args[destination.Index++] = ptr;
- mpz_init(ptr);
+ context.Options = (EvaluationOptions) (context.Options | (1 << context.Index));
+ auto ptr = &context.Temp[context.Index].MPTYPE_NAME;
+ CTXT(context.Index++) = ptr;
+ MP(init)(ptr);
AssignTo(ptr);
}
@@ -361,7 +95,7 @@ namespace MPIR
/// Source value to add to
/// Source value to add
/// An expression object that, when assigned to the Value property or consumed by a primitive-returning method, computes the requested operation
- static IntegerExpression^ operator + (IntegerExpression^ a, IntegerExpression^ b);
+ static MPEXPR_NAME^ operator + (MPEXPR_NAME^ a, MPEXPR_NAME^ b);
/// Adds two numbers.
/// As with all expressions, the result is not computed until the expression is assigned to the Value property or consumed by a method.
@@ -369,7 +103,7 @@ namespace MPIR
/// Source value to add to
/// Source value to add
/// An expression object that, when assigned to the Value property or consumed by a primitive-returning method, computes the requested operation
- static IntegerExpression^ operator + (IntegerExpression^ a, mpir_ui b);
+ static MPEXPR_NAME^ operator + (MPEXPR_NAME^ a, mpir_ui b);
/// Adds two numbers.
/// As with all expressions, the result is not computed until the expression is assigned to the Value property or consumed by a method.
@@ -377,7 +111,7 @@ namespace MPIR
/// Source value to add to
/// Source value to add
/// An expression object that, when assigned to the Value property or consumed by a primitive-returning method, computes the requested operation
- static IntegerExpression^ operator + (mpir_ui a, IntegerExpression^ b);
+ static MPEXPR_NAME^ operator + (mpir_ui a, MPEXPR_NAME^ b);
/// Adds two numbers.
/// As with all expressions, the result is not computed until the expression is assigned to the Value property or consumed by a method.
@@ -385,7 +119,7 @@ namespace MPIR
/// Source value to add to
/// Source value to add
/// An expression object that, when assigned to the Value property or consumed by a primitive-returning method, computes the requested operation
- static IntegerExpression^ operator + (IntegerExpression^ a, mpir_si b);
+ static MPEXPR_NAME^ operator + (MPEXPR_NAME^ a, mpir_si b);
/// Adds two numbers.
/// As with all expressions, the result is not computed until the expression is assigned to the Value property or consumed by a method.
@@ -393,7 +127,7 @@ namespace MPIR
/// Source value to add to
/// Source value to add
/// An expression object that, when assigned to the Value property or consumed by a primitive-returning method, computes the requested operation
- static IntegerExpression^ operator + (mpir_si a, IntegerExpression^ b);
+ static MPEXPR_NAME^ operator + (mpir_si a, MPEXPR_NAME^ b);
/// Subtracts two numbers.
/// As with all expressions, the result is not computed until the expression is assigned to the Value property or consumed by a method.
@@ -401,7 +135,7 @@ namespace MPIR
/// Source value to subtract from
/// Source value to subtract
/// An expression object that, when assigned to the Value property or consumed by a primitive-returning method, computes the requested operation
- static IntegerExpression^ operator - (IntegerExpression^ a, IntegerExpression^ b);
+ static MPEXPR_NAME^ operator - (MPEXPR_NAME^ a, MPEXPR_NAME^ b);
/// Subtracts two numbers.
/// As with all expressions, the result is not computed until the expression is assigned to the Value property or consumed by a method.
@@ -409,7 +143,7 @@ namespace MPIR
/// Source value to subtract from
/// Source value to subtract
/// An expression object that, when assigned to the Value property or consumed by a primitive-returning method, computes the requested operation
- static IntegerExpression^ operator - (IntegerExpression^ a, mpir_ui b);
+ static MPEXPR_NAME^ operator - (MPEXPR_NAME^ a, mpir_ui b);
/// Subtracts two numbers.
/// As with all expressions, the result is not computed until the expression is assigned to the Value property or consumed by a method.
@@ -417,7 +151,7 @@ namespace MPIR
/// Source value to subtract from
/// Source value to subtract
/// An expression object that, when assigned to the Value property or consumed by a primitive-returning method, computes the requested operation
- static IntegerExpression^ operator - (mpir_ui a, IntegerExpression^ b);
+ static MPEXPR_NAME^ operator - (mpir_ui a, MPEXPR_NAME^ b);
/// Subtracts two numbers.
/// As with all expressions, the result is not computed until the expression is assigned to the Value property or consumed by a method.
@@ -425,7 +159,7 @@ namespace MPIR
/// Source value to subtract from
/// Source value to subtract
/// An expression object that, when assigned to the Value property or consumed by a primitive-returning method, computes the requested operation
- static IntegerExpression^ operator - (IntegerExpression^ a, mpir_si b);
+ static MPEXPR_NAME^ operator - (MPEXPR_NAME^ a, mpir_si b);
/// Subtracts two numbers.
/// As with all expressions, the result is not computed until the expression is assigned to the Value property or consumed by a method.
@@ -433,7 +167,7 @@ namespace MPIR
/// Source value to subtract from
/// Source value to subtract
/// An expression object that, when assigned to the Value property or consumed by a primitive-returning method, computes the requested operation
- static IntegerExpression^ operator - (mpir_si a, IntegerExpression^ b);
+ static MPEXPR_NAME^ operator - (mpir_si a, MPEXPR_NAME^ b);
/// Multiplies two numbers.
/// As with all expressions, the result is not computed until the expression is assigned to the Value property or consumed by a method.
@@ -441,7 +175,7 @@ namespace MPIR
/// Source value to multiply
/// Source value to multiply by
/// An expression object that, when assigned to the Value property or consumed by a primitive-returning method, computes the requested operation
- static IntegerExpression^ operator * (IntegerExpression^ a, IntegerExpression^ b);
+ static MPEXPR_NAME^ operator * (MPEXPR_NAME^ a, MPEXPR_NAME^ b);
/// Multiplies two numbers.
/// As with all expressions, the result is not computed until the expression is assigned to the Value property or consumed by a method.
@@ -449,7 +183,7 @@ namespace MPIR
/// Source value to multiply
/// Source value to multiply by
/// An expression object that, when assigned to the Value property or consumed by a primitive-returning method, computes the requested operation
- static IntegerExpression^ operator * (IntegerExpression^ a, mpir_ui b);
+ static MPEXPR_NAME^ operator * (MPEXPR_NAME^ a, mpir_ui b);
/// Multiplies two numbers.
/// As with all expressions, the result is not computed until the expression is assigned to the Value property or consumed by a method.
@@ -457,7 +191,7 @@ namespace MPIR
/// Source value to multiply
/// Source value to multiply by
/// An expression object that, when assigned to the Value property or consumed by a primitive-returning method, computes the requested operation
- static IntegerExpression^ operator * (mpir_ui a, IntegerExpression^ b);
+ static MPEXPR_NAME^ operator * (mpir_ui a, MPEXPR_NAME^ b);
/// Multiplies two numbers.
/// As with all expressions, the result is not computed until the expression is assigned to the Value property or consumed by a method.
@@ -465,7 +199,7 @@ namespace MPIR
/// Source value to multiply
/// Source value to multiply by
/// An expression object that, when assigned to the Value property or consumed by a primitive-returning method, computes the requested operation
- static IntegerExpression^ operator * (IntegerExpression^ a, mpir_si b);
+ static MPEXPR_NAME^ operator * (MPEXPR_NAME^ a, mpir_si b);
/// Multiplies two numbers.
/// As with all expressions, the result is not computed until the expression is assigned to the Value property or consumed by a method.
@@ -473,7 +207,7 @@ namespace MPIR
/// Source value to multiply
/// Source value to multiply by
/// An expression object that, when assigned to the Value property or consumed by a primitive-returning method, computes the requested operation
- static IntegerExpression^ operator * (mpir_si a, IntegerExpression^ b);
+ static MPEXPR_NAME^ operator * (mpir_si a, MPEXPR_NAME^ b);
/// Shifts the source operand to the left by , i.e. multiplies by 2^.
/// As with all expressions, the result is not computed until the expression is assigned to the Value property or consumed by a method.
@@ -481,7 +215,7 @@ namespace MPIR
/// Source value to multiply
/// Number of bits to shift by, i.e. power of 2 to multiply by
/// An expression object that, when assigned to the Value property or consumed by a primitive-returning method, computes the requested operation
- static IntegerExpression^ operator << (IntegerExpression^ a, mp_bitcnt_t bits);
+ static MPEXPR_NAME^ operator << (MPEXPR_NAME^ a, mp_bitcnt_t bits);
/// Shifts the source operand to the right by , i.e. divides by 2^.
/// As with all expressions, the result is not computed until the expression is assigned to the Value property or consumed by a method.
@@ -493,14 +227,14 @@ namespace MPIR
/// The expression exposes methods you can call to select whether you need to compute the quotient or remainder of the division, and/or to set the rounding mode.
/// By default, the shifted value (i.e., quotient) is computed and the rounding mode defaults to the static MpirSettings.DefaultRoundingMode.
///
- static IntegerShiftRightExpression^ operator >> (IntegerExpression^ a, mp_bitcnt_t bits);
+ static MPEXPR(ShiftRight)^ operator >> (MPEXPR_NAME^ a, mp_bitcnt_t bits);
/// Negates the source value.
/// As with all expressions, the result is not computed until the expression is assigned to the Value property or consumed by a method.
///
/// Source value to negate
/// An expression object that, when assigned to the Value property or consumed by a primitive-returning method, computes the requested operation
- static IntegerExpression^ operator - (IntegerExpression^ a);
+ static MPEXPR_NAME^ operator - (MPEXPR_NAME^ a);
/// Divides two numbers.
/// As with all expressions, the result is not computed until the expression is assigned to the Value property or consumed by a method.
@@ -511,7 +245,7 @@ namespace MPIR
/// The expression exposes methods you can call optionally if you need to save the remainder of the division, and/or to set the rounding mode.
/// By default, the remainder is not computed and the rounding mode defaults to the static MpirSettings.DefaultRoundingMode.
///
- static IntegerDivideExpression^ operator / (IntegerExpression^ a, IntegerExpression^ b);
+ static MPEXPR(Divide)^ operator / (MPEXPR_NAME^ a, MPEXPR_NAME^ b);
/// Divides two numbers.
/// As with all expressions, the result is not computed until the expression is assigned to the Value property or consumed by a method.
@@ -522,7 +256,7 @@ namespace MPIR
/// The expression exposes methods you can call optionally if you need to save the remainder of the division, and/or to set the rounding mode.
/// By default, the remainder is not computed and the rounding mode defaults to the static MpirSettings.DefaultRoundingMode.
///
- static IntegerDivideUiExpression^ operator / (IntegerExpression^ a, mpir_ui b);
+ static MPEXPR(DivideUi)^ operator / (MPEXPR_NAME^ a, mpir_ui b);
/// Calculates the remainder from the division of two numbers.
/// As with all expressions, the result is not computed until the expression is assigned to the Value property or consumed by a method.
@@ -534,7 +268,7 @@ namespace MPIR
/// The expression exposes methods you can call optionally if you need to save the quotient in addition to the remainder, and/or to set the rounding mode.
/// By default, the remainder is not computed and the rounding mode defaults to the static MpirSettings.DefaultRoundingMode.
///
- static IntegerModExpression^ operator % (IntegerExpression^ a, IntegerExpression^ b);
+ static MPEXPR(Mod)^ operator % (MPEXPR_NAME^ a, MPEXPR_NAME^ b);
/// Calculates the remainder from the division of two numbers.
/// As with all expressions, the result is not computed until the expression is assigned to the Value property or consumed by a method.
@@ -546,7 +280,7 @@ namespace MPIR
/// The expression exposes methods you can call optionally if you need to save the quotient in addition to the remainder, and/or to set the rounding mode.
/// By default, the remainder is not computed and the rounding mode defaults to the static MpirSettings.DefaultRoundingMode.
///
- static IntegerModUiExpression^ operator % (IntegerExpression^ a, mpir_ui b);
+ static MPEXPR(ModUi)^ operator % (MPEXPR_NAME^ a, mpir_ui b);
/// Raises the source value to the specified power.
/// As with all expressions, the result is not computed until the expression is assigned to the Value property or consumed by a method.
@@ -554,7 +288,7 @@ namespace MPIR
/// Source value to multiply
/// Power to raise to
/// An expression object that, when assigned to the Value property or consumed by a primitive-returning method, computes the requested operation
- static IntegerExpression^ operator ^ (IntegerExpression^ a, mpir_ui power);
+ static MPEXPR_NAME^ operator ^ (MPEXPR_NAME^ a, mpir_ui power);
/// Computes the bitwise AND of two numbers.
/// As with all expressions, the result is not computed until the expression is assigned to the Value property or consumed by a method.
@@ -562,7 +296,7 @@ namespace MPIR
/// Source value to AND
/// Source value to AND with
/// An expression object that, when assigned to the Value property or consumed by a primitive-returning method, computes the requested operation
- static IntegerExpression^ operator & (IntegerExpression^ a, IntegerExpression^ b);
+ static MPEXPR_NAME^ operator & (MPEXPR_NAME^ a, MPEXPR_NAME^ b);
/// Computes the bitwise (inclusive) OR of two numbers.
/// As with all expressions, the result is not computed until the expression is assigned to the Value property or consumed by a method.
@@ -570,7 +304,7 @@ namespace MPIR
/// Source value to OR
/// Source value to OR with
/// An expression object that, when assigned to the Value property or consumed by a primitive-returning method, computes the requested operation
- static IntegerExpression^ operator | (IntegerExpression^ a, IntegerExpression^ b);
+ static MPEXPR_NAME^ operator | (MPEXPR_NAME^ a, MPEXPR_NAME^ b);
/// Computes the bitwise XOR (exclusive or) of two numbers.
/// As with all expressions, the result is not computed until the expression is assigned to the Value property or consumed by a method.
@@ -578,21 +312,21 @@ namespace MPIR
/// Source value to XOR
/// Source value to XOR with
/// An expression object that, when assigned to the Value property or consumed by a primitive-returning method, computes the requested operation
- static IntegerExpression^ operator ^ (IntegerExpression^ a, IntegerExpression^ b);
+ static MPEXPR_NAME^ operator ^ (MPEXPR_NAME^ a, MPEXPR_NAME^ b);
/// Computes the bitwise complement of a number.
/// As with all expressions, the result is not computed until the expression is assigned to the Value property or consumed by a method.
///
/// Source value to complement
/// An expression object that, when assigned to the Value property or consumed by a primitive-returning method, computes the requested operation
- static IntegerExpression^ operator ~ (IntegerExpression^ a);
+ static MPEXPR_NAME^ operator ~ (MPEXPR_NAME^ a);
/// If the source is >= 0, returns the population count of op, which is the number of 1 bits in the binary representation.
/// If the source is < 0, the number of 1s is infinite, and the return value is ulong.MaxValue, the largest possible bit count.
/// Because the result is a primitive type, it is computed immediately.
///
/// The population count for a non-negative number
- mp_bitcnt_t PopCount() { IN_CONTEXT(this); return mpz_popcount(context.Args[0]); }
+ mp_bitcnt_t PopCount() { IN_CONTEXT(this); return MP(popcount)(CTXT(0)); }
/// If this number and the operand are both >= 0 or both < 0, returns the hamming distance between them, which is the number of bit positions with different bit values.
/// If one operand is >= 0 and the other < 0 then the number of bits different is infinite, and the return value is ulong.MaxValue, the largest possible bit count.
@@ -600,7 +334,7 @@ namespace MPIR
///
/// Source value to compute the hamming distance to
/// The hamming distance between this number and
- mp_bitcnt_t HammingDistance(IntegerExpression^ a) { IN_CONTEXT(this, a); return mpz_hamdist(context.Args[0], context.Args[1]); }
+ mp_bitcnt_t HammingDistance(MPEXPR_NAME^ a) { IN_CONTEXT(this, a); return MP(hamdist)(CTXT(0), CTXT(1)); }
/// Scans the source number, starting from the bit, towards more significant bits, until the first 0 or 1 bit
/// (depending on the is found, and return the index of the found bit.
@@ -612,13 +346,13 @@ namespace MPIR
/// Value of the bit to scan for, true for 1, false for 0
/// Starting bit position to search. The least significant bit is zero.
/// The index of the found bit, or ulong.MaxValue if no bit found.
- mp_bitcnt_t FindBit(bool value, mp_bitcnt_t start) { IN_CONTEXT(this); return value ? mpz_scan1(context.Args[0], start) : mpz_scan0(context.Args[0], start); }
+ mp_bitcnt_t FindBit(bool value, mp_bitcnt_t start) { IN_CONTEXT(this); return value ? MP(scan1)(CTXT(0), start) : MP(scan0)(CTXT(0), start); }
/// Computes the absolute value of the source number.
/// As with all expressions, the result is not computed until the expression is assigned to the Value property or consumed by a method.
///
/// An expression object that, when assigned to the Value property or consumed by a primitive-returning method, computes the requested operation
- IntegerExpression^ Abs();
+ MPEXPR_NAME^ Abs();
/// Divides two numbers where it is known in advance that the division is exact. This method is faster than normal division,
/// but produces an undefined result when the division is not exact.
@@ -627,7 +361,7 @@ namespace MPIR
/// Source value to divide by
/// An expression object that, when assigned to the Value property or consumed by a primitive-returning method, computes the requested operation.
///
- IntegerExpression^ DivideExactly(IntegerExpression^ a);
+ MPEXPR_NAME^ DivideExactly(MPEXPR_NAME^ a);
/// Divides two numbers where it is known in advance that the division is exact. This method is faster than normal division,
/// but produces an undefined result when the division is not exact.
@@ -636,7 +370,7 @@ namespace MPIR
/// Source value to divide by
/// An expression object that, when assigned to the Value property or consumed by a primitive-returning method, computes the requested operation.
///
- IntegerExpression^ DivideExactly(mpir_ui a);
+ MPEXPR_NAME^ DivideExactly(mpir_ui a);
/// Raises the source value to the specified modulo .
/// As with all expressions, the result is not computed until the expression is assigned to the Value property or consumed by a method.
@@ -645,7 +379,7 @@ namespace MPIR
/// Negative power values are supported if an inverse mod exists, otherwise divide by zero is raised.
/// Modulo to perform the powering operation with
/// An expression object that, when assigned to the Value property or consumed by a primitive-returning method, computes the requested operation
- IntegerExpression^ PowerMod(IntegerExpression^ power, IntegerExpression^ modulo);
+ MPEXPR_NAME^ PowerMod(MPEXPR_NAME^ power, MPEXPR_NAME^ modulo);
/// Raises the source value to the specified modulo .
/// As with all expressions, the result is not computed until the expression is assigned to the Value property or consumed by a method.
@@ -653,7 +387,7 @@ namespace MPIR
/// Power to raise the source value to
/// Modulo to perform the powering operation with
/// An expression object that, when assigned to the Value property or consumed by a primitive-returning method, computes the requested operation
- IntegerExpression^ PowerMod(mpir_ui power, IntegerExpression^ modulo);
+ MPEXPR_NAME^ PowerMod(mpir_ui power, MPEXPR_NAME^ modulo);
/// Computes the truncated integer part of the root of the specified from the source value.
/// As with all expressions, the result is not computed until the expression is assigned to the Value property or consumed by a method.
@@ -661,14 +395,14 @@ namespace MPIR
/// by calling a method on the resulting expression, before assigning it.
/// Power of the root to compute.
/// An expression object that, when assigned to the Value property or consumed by a primitive-returning method, computes the requested operation
- IntegerRootExpression^ Root(mpir_ui power);
+ MPEXPR(Root)^ Root(mpir_ui power);
/// Computes the truncated integer part of the square root of the source value.
/// As with all expressions, the result is not computed until the expression is assigned to the Value property or consumed by a method.
/// You can optionally save the remainder from the root operation
/// by calling a method on the resulting expression, before assigning it.
/// An expression object that, when assigned to the Value property or consumed by a primitive-returning method, computes the requested operation
- IntegerSquareRootExpression^ SquareRoot();
+ MPEXPR(SquareRoot)^ SquareRoot();
/// Calculates the remainder from the division of two numbers, using the rounding mode set in MpirSettings.RoundingMode.
/// Because the result is a primitive type, it is computed immediately.
@@ -701,14 +435,14 @@ namespace MPIR
///
/// Value to compare the source with
/// A positive number if the source is greater than , negative if less, and zero if they are equal.
- virtual int CompareTo(IntegerExpression^ a) sealed;
+ virtual int CompareTo(MPEXPR_NAME^ a) sealed;
/// Compares two numbers.
/// If any argument is an expression, it is evaluated into a temporary variable before the comparison is performed.
///
/// Value to compare the source with
/// true if the values of the source and are equal, false otherwise.
- virtual bool Equals(IntegerExpression^ a) sealed;
+ virtual bool Equals(MPEXPR_NAME^ a) sealed;
/// Compares two numbers.
/// If any argument is an expression, it is evaluated into a temporary variable before the comparison is performed.
@@ -730,7 +464,7 @@ namespace MPIR
/// Source value to compare
/// Source value to compare with
/// A boolean result of the comparison.
- static bool operator < (IntegerExpression^ a, IntegerExpression^ b) { return IS_NULL(a) ? !IS_NULL(b) : a->CompareTo(b) < 0; }
+ static bool operator < (MPEXPR_NAME^ a, MPEXPR_NAME^ b) { return IS_NULL(a) ? !IS_NULL(b) : a->CompareTo(b) < 0; }
/// Compares two numbers.
/// If any argument is an expression, it is evaluated into a temporary variable before the comparison is performed.
@@ -738,7 +472,7 @@ namespace MPIR
/// Source value to compare
/// Source value to compare with
/// A boolean result of the comparison.
- static bool operator >= (IntegerExpression^ a, IntegerExpression^ b) { return IS_NULL(a) ? IS_NULL(b) : a->CompareTo(b) >= 0; }
+ static bool operator >= (MPEXPR_NAME^ a, MPEXPR_NAME^ b) { return IS_NULL(a) ? IS_NULL(b) : a->CompareTo(b) >= 0; }
/// Compares two numbers.
/// If any argument is an expression, it is evaluated into a temporary variable before the comparison is performed.
@@ -746,7 +480,7 @@ namespace MPIR
/// Source value to compare
/// Source value to compare with
/// A boolean result of the comparison.
- static bool operator == (IntegerExpression^ a, IntegerExpression^ b) { return IS_NULL(a) ? IS_NULL(b) : a->CompareTo(b) == 0; }
+ static bool operator == (MPEXPR_NAME^ a, MPEXPR_NAME^ b) { return IS_NULL(a) ? IS_NULL(b) : a->CompareTo(b) == 0; }
/// Compares two numbers.
/// If any argument is an expression, it is evaluated into a temporary variable before the comparison is performed.
@@ -754,7 +488,7 @@ namespace MPIR
/// Source value to compare
/// Source value to compare with
/// A boolean result of the comparison.
- static bool operator != (IntegerExpression^ a, IntegerExpression^ b) { return IS_NULL(a) ? !IS_NULL(b) : a->CompareTo(b) != 0; }
+ static bool operator != (MPEXPR_NAME^ a, MPEXPR_NAME^ b) { return IS_NULL(a) ? !IS_NULL(b) : a->CompareTo(b) != 0; }
/// Compares two numbers.
/// If any argument is an expression, it is evaluated into a temporary variable before the comparison is performed.
@@ -762,7 +496,7 @@ namespace MPIR
/// Source value to compare
/// Source value to compare with
/// A boolean result of the comparison.
- static bool operator > (IntegerExpression^ a, IntegerExpression^ b) { return !IS_NULL(a) && a->CompareTo(b) > 0; }
+ static bool operator > (MPEXPR_NAME^ a, MPEXPR_NAME^ b) { return !IS_NULL(a) && a->CompareTo(b) > 0; }
/// Compares two numbers.
/// If any argument is an expression, it is evaluated into a temporary variable before the comparison is performed.
@@ -770,7 +504,7 @@ namespace MPIR
/// Source value to compare
/// Source value to compare with
/// A boolean result of the comparison.
- static bool operator <= (IntegerExpression^ a, IntegerExpression^ b) { return IS_NULL(a) || a->CompareTo(b) <= 0; }
+ static bool operator <= (MPEXPR_NAME^ a, MPEXPR_NAME^ b) { return IS_NULL(a) || a->CompareTo(b) <= 0; }
/// Compares two numbers.
/// If any argument is an expression, it is evaluated into a temporary variable before the comparison is performed.
@@ -778,7 +512,7 @@ namespace MPIR
/// Source value to compare
/// Source value to compare with
/// A boolean result of the comparison.
- static bool operator < (IntegerExpression^ a, mpir_ui b) { return IS_NULL(a) || a->CompareTo(b) < 0; }
+ static bool operator < (MPEXPR_NAME^ a, mpir_ui b) { return IS_NULL(a) || a->CompareTo(b) < 0; }
/// Compares two numbers.
/// If any argument is an expression, it is evaluated into a temporary variable before the comparison is performed.
@@ -786,7 +520,7 @@ namespace MPIR
/// Source value to compare
/// Source value to compare with
/// A boolean result of the comparison.
- static bool operator >= (IntegerExpression^ a, mpir_ui b) { return !IS_NULL(a) && a->CompareTo(b) >= 0; }
+ static bool operator >= (MPEXPR_NAME^ a, mpir_ui b) { return !IS_NULL(a) && a->CompareTo(b) >= 0; }
/// Compares two numbers.
/// If any argument is an expression, it is evaluated into a temporary variable before the comparison is performed.
@@ -794,7 +528,7 @@ namespace MPIR
/// Source value to compare
/// Source value to compare with
/// A boolean result of the comparison.
- static bool operator > (IntegerExpression^ a, mpir_ui b) { return !IS_NULL(a) && a->CompareTo(b) > 0; }
+ static bool operator > (MPEXPR_NAME^ a, mpir_ui b) { return !IS_NULL(a) && a->CompareTo(b) > 0; }
/// Compares two numbers.
/// If any argument is an expression, it is evaluated into a temporary variable before the comparison is performed.
@@ -802,7 +536,7 @@ namespace MPIR
/// Source value to compare
/// Source value to compare with
/// A boolean result of the comparison.
- static bool operator <= (IntegerExpression^ a, mpir_ui b) { return IS_NULL(a) || a->CompareTo(b) <= 0; }
+ static bool operator <= (MPEXPR_NAME^ a, mpir_ui b) { return IS_NULL(a) || a->CompareTo(b) <= 0; }
/// Compares two numbers.
/// If any argument is an expression, it is evaluated into a temporary variable before the comparison is performed.
@@ -810,7 +544,7 @@ namespace MPIR
/// Source value to compare
/// Source value to compare with
/// A boolean result of the comparison.
- static bool operator != (IntegerExpression^ a, mpir_ui b) { return IS_NULL(a) || a->CompareTo(b) != 0; }
+ static bool operator != (MPEXPR_NAME^ a, mpir_ui b) { return IS_NULL(a) || a->CompareTo(b) != 0; }
/// Compares two numbers.
/// If any argument is an expression, it is evaluated into a temporary variable before the comparison is performed.
@@ -818,7 +552,7 @@ namespace MPIR
/// Source value to compare
/// Source value to compare with
/// A boolean result of the comparison.
- static bool operator == (IntegerExpression^ a, mpir_ui b) { return !IS_NULL(a) && a->CompareTo(b) == 0; }
+ static bool operator == (MPEXPR_NAME^ a, mpir_ui b) { return !IS_NULL(a) && a->CompareTo(b) == 0; }
/// Compares two numbers.
/// If any argument is an expression, it is evaluated into a temporary variable before the comparison is performed.
@@ -826,7 +560,7 @@ namespace MPIR
/// Source value to compare
/// Source value to compare with
/// A boolean result of the comparison.
- static bool operator < (mpir_ui b, IntegerExpression^ a) { return !IS_NULL(a) && a->CompareTo(b) > 0; }
+ static bool operator < (mpir_ui b, MPEXPR_NAME^ a) { return !IS_NULL(a) && a->CompareTo(b) > 0; }
/// Compares two numbers.
/// If any argument is an expression, it is evaluated into a temporary variable before the comparison is performed.
@@ -834,7 +568,7 @@ namespace MPIR
/// Source value to compare
/// Source value to compare with
/// A boolean result of the comparison.
- static bool operator >= (mpir_ui b, IntegerExpression^ a) { return IS_NULL(a) || a->CompareTo(b) <= 0; }
+ static bool operator >= (mpir_ui b, MPEXPR_NAME^ a) { return IS_NULL(a) || a->CompareTo(b) <= 0; }
/// Compares two numbers.
/// If any argument is an expression, it is evaluated into a temporary variable before the comparison is performed.
@@ -842,7 +576,7 @@ namespace MPIR
/// Source value to compare
/// Source value to compare with
/// A boolean result of the comparison.
- static bool operator > (mpir_ui b, IntegerExpression^ a) { return IS_NULL(a) || a->CompareTo(b) < 0; }
+ static bool operator > (mpir_ui b, MPEXPR_NAME^ a) { return IS_NULL(a) || a->CompareTo(b) < 0; }
/// Compares two numbers.
/// If any argument is an expression, it is evaluated into a temporary variable before the comparison is performed.
@@ -850,7 +584,7 @@ namespace MPIR
/// Source value to compare
/// Source value to compare with
/// A boolean result of the comparison.
- static bool operator <= (mpir_ui b, IntegerExpression^ a) { return !IS_NULL(a) && a->CompareTo(b) >= 0; }
+ static bool operator <= (mpir_ui b, MPEXPR_NAME^ a) { return !IS_NULL(a) && a->CompareTo(b) >= 0; }
/// Compares two numbers.
/// If any argument is an expression, it is evaluated into a temporary variable before the comparison is performed.
@@ -858,7 +592,7 @@ namespace MPIR
/// Source value to compare
/// Source value to compare with
/// A boolean result of the comparison.
- static bool operator != (mpir_ui b, IntegerExpression^ a) { return IS_NULL(a) || a->CompareTo(b) != 0; }
+ static bool operator != (mpir_ui b, MPEXPR_NAME^ a) { return IS_NULL(a) || a->CompareTo(b) != 0; }
/// Compares two numbers.
/// If any argument is an expression, it is evaluated into a temporary variable before the comparison is performed.
@@ -866,7 +600,7 @@ namespace MPIR
/// Source value to compare
/// Source value to compare with
/// A boolean result of the comparison.
- static bool operator == (mpir_ui b, IntegerExpression^ a) { return !IS_NULL(a) && a->CompareTo(b) == 0; }
+ static bool operator == (mpir_ui b, MPEXPR_NAME^ a) { return !IS_NULL(a) && a->CompareTo(b) == 0; }
/// Compares two numbers.
/// If any argument is an expression, it is evaluated into a temporary variable before the comparison is performed.
@@ -874,7 +608,7 @@ namespace MPIR
/// Source value to compare
/// Source value to compare with
/// A boolean result of the comparison.
- static bool operator < (IntegerExpression^ a, mpir_si b) { return IS_NULL(a) || a->CompareTo(b) < 0; }
+ static bool operator < (MPEXPR_NAME^ a, mpir_si b) { return IS_NULL(a) || a->CompareTo(b) < 0; }
/// Compares two numbers.
/// If any argument is an expression, it is evaluated into a temporary variable before the comparison is performed.
@@ -882,7 +616,7 @@ namespace MPIR
/// Source value to compare
/// Source value to compare with
/// A boolean result of the comparison.
- static bool operator >= (IntegerExpression^ a, mpir_si b) { return !IS_NULL(a) && a->CompareTo(b) >= 0; }
+ static bool operator >= (MPEXPR_NAME^ a, mpir_si b) { return !IS_NULL(a) && a->CompareTo(b) >= 0; }
/// Compares two numbers.
/// If any argument is an expression, it is evaluated into a temporary variable before the comparison is performed.
@@ -890,7 +624,7 @@ namespace MPIR
/// Source value to compare
/// Source value to compare with
/// A boolean result of the comparison.
- static bool operator > (IntegerExpression^ a, mpir_si b) { return !IS_NULL(a) && a->CompareTo(b) > 0; }
+ static bool operator > (MPEXPR_NAME^ a, mpir_si b) { return !IS_NULL(a) && a->CompareTo(b) > 0; }
/// Compares two numbers.
/// If any argument is an expression, it is evaluated into a temporary variable before the comparison is performed.
@@ -898,7 +632,7 @@ namespace MPIR
/// Source value to compare
/// Source value to compare with
/// A boolean result of the comparison.
- static bool operator <= (IntegerExpression^ a, mpir_si b) { return IS_NULL(a) || a->CompareTo(b) <= 0; }
+ static bool operator <= (MPEXPR_NAME^ a, mpir_si b) { return IS_NULL(a) || a->CompareTo(b) <= 0; }
/// Compares two numbers.
/// If any argument is an expression, it is evaluated into a temporary variable before the comparison is performed.
@@ -906,7 +640,7 @@ namespace MPIR
/// Source value to compare
/// Source value to compare with
/// A boolean result of the comparison.
- static bool operator != (IntegerExpression^ a, mpir_si b) { return IS_NULL(a) || a->CompareTo(b) != 0; }
+ static bool operator != (MPEXPR_NAME^ a, mpir_si b) { return IS_NULL(a) || a->CompareTo(b) != 0; }
/// Compares two numbers.
/// If any argument is an expression, it is evaluated into a temporary variable before the comparison is performed.
@@ -914,7 +648,7 @@ namespace MPIR
/// Source value to compare
/// Source value to compare with
/// A boolean result of the comparison.
- static bool operator == (IntegerExpression^ a, mpir_si b) { return !IS_NULL(a) && a->CompareTo(b) == 0; }
+ static bool operator == (MPEXPR_NAME^ a, mpir_si b) { return !IS_NULL(a) && a->CompareTo(b) == 0; }
/// Compares two numbers.
/// If any argument is an expression, it is evaluated into a temporary variable before the comparison is performed.
@@ -922,7 +656,7 @@ namespace MPIR
/// Source value to compare
/// Source value to compare with
/// A boolean result of the comparison.
- static bool operator < (mpir_si b, IntegerExpression^ a) { return !IS_NULL(a) && a->CompareTo(b) > 0; }
+ static bool operator < (mpir_si b, MPEXPR_NAME^ a) { return !IS_NULL(a) && a->CompareTo(b) > 0; }
/// Compares two numbers.
/// If any argument is an expression, it is evaluated into a temporary variable before the comparison is performed.
@@ -930,7 +664,7 @@ namespace MPIR
/// Source value to compare
/// Source value to compare with
/// A boolean result of the comparison.
- static bool operator >= (mpir_si b, IntegerExpression^ a) { return IS_NULL(a) || a->CompareTo(b) <= 0; }
+ static bool operator >= (mpir_si b, MPEXPR_NAME^ a) { return IS_NULL(a) || a->CompareTo(b) <= 0; }
/// Compares two numbers.
/// If any argument is an expression, it is evaluated into a temporary variable before the comparison is performed.
@@ -938,7 +672,7 @@ namespace MPIR
/// Source value to compare
/// Source value to compare with
/// A boolean result of the comparison.
- static bool operator > (mpir_si b, IntegerExpression^ a) { return IS_NULL(a) || a->CompareTo(b) < 0; }
+ static bool operator > (mpir_si b, MPEXPR_NAME^ a) { return IS_NULL(a) || a->CompareTo(b) < 0; }
/// Compares two numbers.
/// If any argument is an expression, it is evaluated into a temporary variable before the comparison is performed.
@@ -946,7 +680,7 @@ namespace MPIR
/// Source value to compare
/// Source value to compare with
/// A boolean result of the comparison.
- static bool operator <= (mpir_si b, IntegerExpression^ a) { return !IS_NULL(a) && a->CompareTo(b) >= 0; }
+ static bool operator <= (mpir_si b, MPEXPR_NAME^ a) { return !IS_NULL(a) && a->CompareTo(b) >= 0; }
/// Compares two numbers.
/// If any argument is an expression, it is evaluated into a temporary variable before the comparison is performed.
@@ -954,7 +688,7 @@ namespace MPIR
/// Source value to compare
/// Source value to compare with
/// A boolean result of the comparison.
- static bool operator != (mpir_si b, IntegerExpression^ a) { return IS_NULL(a) || a->CompareTo(b) != 0; }
+ static bool operator != (mpir_si b, MPEXPR_NAME^ a) { return IS_NULL(a) || a->CompareTo(b) != 0; }
/// Compares two numbers.
/// If any argument is an expression, it is evaluated into a temporary variable before the comparison is performed.
@@ -962,7 +696,7 @@ namespace MPIR
/// Source value to compare
/// Source value to compare with
/// A boolean result of the comparison.
- static bool operator == (mpir_si b, IntegerExpression^ a) { return !IS_NULL(a) && a->CompareTo(b) == 0; }
+ static bool operator == (mpir_si b, MPEXPR_NAME^ a) { return !IS_NULL(a) && a->CompareTo(b) == 0; }
/// Compares two numbers.
/// If any argument is an expression, it is evaluated into a temporary variable before the comparison is performed.
@@ -970,7 +704,7 @@ namespace MPIR
/// Source value to compare
/// Source value to compare with
/// A boolean result of the comparison.
- static bool operator < (IntegerExpression^ a, double b) { return IS_NULL(a) || a->CompareTo(b) < 0; }
+ static bool operator < (MPEXPR_NAME^ a, double b) { return IS_NULL(a) || a->CompareTo(b) < 0; }
/// Compares two numbers.
/// If any argument is an expression, it is evaluated into a temporary variable before the comparison is performed.
@@ -978,7 +712,7 @@ namespace MPIR
/// Source value to compare
/// Source value to compare with
/// A boolean result of the comparison.
- static bool operator >= (IntegerExpression^ a, double b) { return !IS_NULL(a) && a->CompareTo(b) >= 0; }
+ static bool operator >= (MPEXPR_NAME^ a, double b) { return !IS_NULL(a) && a->CompareTo(b) >= 0; }
/// Compares two numbers.
/// If any argument is an expression, it is evaluated into a temporary variable before the comparison is performed.
@@ -986,7 +720,7 @@ namespace MPIR
/// Source value to compare
/// Source value to compare with
/// A boolean result of the comparison.
- static bool operator > (IntegerExpression^ a, double b) { return !IS_NULL(a) && a->CompareTo(b) > 0; }
+ static bool operator > (MPEXPR_NAME^ a, double b) { return !IS_NULL(a) && a->CompareTo(b) > 0; }
/// Compares two numbers.
/// If any argument is an expression, it is evaluated into a temporary variable before the comparison is performed.
@@ -994,7 +728,7 @@ namespace MPIR
/// Source value to compare
/// Source value to compare with
/// A boolean result of the comparison.
- static bool operator <= (IntegerExpression^ a, double b) { return IS_NULL(a) || a->CompareTo(b) <= 0; }
+ static bool operator <= (MPEXPR_NAME^ a, double b) { return IS_NULL(a) || a->CompareTo(b) <= 0; }
/// Compares two numbers.
/// If any argument is an expression, it is evaluated into a temporary variable before the comparison is performed.
@@ -1002,7 +736,7 @@ namespace MPIR
/// Source value to compare
/// Source value to compare with
/// A boolean result of the comparison.
- static bool operator != (IntegerExpression^ a, double b) { return IS_NULL(a) || a->CompareTo(b) != 0; }
+ static bool operator != (MPEXPR_NAME^ a, double b) { return IS_NULL(a) || a->CompareTo(b) != 0; }
/// Compares two numbers.
/// If any argument is an expression, it is evaluated into a temporary variable before the comparison is performed.
@@ -1010,7 +744,7 @@ namespace MPIR
/// Source value to compare
/// Source value to compare with
/// A boolean result of the comparison.
- static bool operator == (IntegerExpression^ a, double b) { return !IS_NULL(a) && a->CompareTo(b) == 0; }
+ static bool operator == (MPEXPR_NAME^ a, double b) { return !IS_NULL(a) && a->CompareTo(b) == 0; }
/// Compares two numbers.
/// If any argument is an expression, it is evaluated into a temporary variable before the comparison is performed.
@@ -1018,7 +752,7 @@ namespace MPIR
/// Source value to compare
/// Source value to compare with
/// A boolean result of the comparison.
- static bool operator < (double b, IntegerExpression^ a) { return !IS_NULL(a) && a->CompareTo(b) > 0; }
+ static bool operator < (double b, MPEXPR_NAME^ a) { return !IS_NULL(a) && a->CompareTo(b) > 0; }
/// Compares two numbers.
/// If any argument is an expression, it is evaluated into a temporary variable before the comparison is performed.
@@ -1026,7 +760,7 @@ namespace MPIR
/// Source value to compare
/// Source value to compare with
/// A boolean result of the comparison.
- static bool operator >= (double b, IntegerExpression^ a) { return IS_NULL(a) || a->CompareTo(b) <= 0; }
+ static bool operator >= (double b, MPEXPR_NAME^ a) { return IS_NULL(a) || a->CompareTo(b) <= 0; }
/// Compares two numbers.
/// If any argument is an expression, it is evaluated into a temporary variable before the comparison is performed.
@@ -1034,7 +768,7 @@ namespace MPIR
/// Source value to compare
/// Source value to compare with
/// A boolean result of the comparison.
- static bool operator > (double b, IntegerExpression^ a) { return IS_NULL(a) || a->CompareTo(b) < 0; }
+ static bool operator > (double b, MPEXPR_NAME^ a) { return IS_NULL(a) || a->CompareTo(b) < 0; }
/// Compares two numbers.
/// If any argument is an expression, it is evaluated into a temporary variable before the comparison is performed.
@@ -1042,7 +776,7 @@ namespace MPIR
/// Source value to compare
/// Source value to compare with
/// A boolean result of the comparison.
- static bool operator <= (double b, IntegerExpression^ a) { return !IS_NULL(a) && a->CompareTo(b) >= 0; }
+ static bool operator <= (double b, MPEXPR_NAME^ a) { return !IS_NULL(a) && a->CompareTo(b) >= 0; }
/// Compares two numbers.
/// If any argument is an expression, it is evaluated into a temporary variable before the comparison is performed.
@@ -1050,7 +784,7 @@ namespace MPIR
/// Source value to compare
/// Source value to compare with
/// A boolean result of the comparison.
- static bool operator != (double b, IntegerExpression^ a) { return IS_NULL(a) || a->CompareTo(b) != 0; }
+ static bool operator != (double b, MPEXPR_NAME^ a) { return IS_NULL(a) || a->CompareTo(b) != 0; }
/// Compares two numbers.
/// If any argument is an expression, it is evaluated into a temporary variable before the comparison is performed.
@@ -1058,34 +792,34 @@ namespace MPIR
/// Source value to compare
/// Source value to compare with
/// A boolean result of the comparison.
- static bool operator == (double b, IntegerExpression^ a) { return !IS_NULL(a) && a->CompareTo(b) == 0; }
+ static bool operator == (double b, MPEXPR_NAME^ a) { return !IS_NULL(a) && a->CompareTo(b) == 0; }
/// Compares the absolute values of two numbers.
/// If any argument is an expression, it is evaluated into a temporary variable before the comparison is performed.
///
/// Value to compare the source with
/// A positive number if the absolute value of the source is greater than the absolute value of , negative if less, and zero if they are equal.
- int CompareAbsTo(IntegerExpression^ a) { IN_CONTEXT(this, a); return mpz_cmpabs(context.Args[0], context.Args[1]); }
+ int CompareAbsTo(MPEXPR_NAME^ a) { IN_CONTEXT(this, a); return MP(cmpabs)(CTXT(0), CTXT(1)); }
/// Compares the absolute values of two numbers.
/// If any argument is an expression, it is evaluated into a temporary variable before the comparison is performed.
///
/// Value to compare the source with
/// A positive number if the absolute value of the source is greater than , negative if less, and zero if they are equal.
- int CompareAbsTo(mpir_ui a) { IN_CONTEXT(this); return mpz_cmpabs_ui(context.Args[0], a); }
+ int CompareAbsTo(mpir_ui a) { IN_CONTEXT(this); return MP(cmpabs_ui)(CTXT(0), a); }
/// Compares the absolute values of two numbers.
/// If any argument is an expression, it is evaluated into a temporary variable before the comparison is performed.
///
/// Value to compare the source with
/// A positive number if the absolute value of the source is greater than the absolute value of , negative if less, and zero if they are equal.
- int CompareAbsTo(double a) { IN_CONTEXT(this); return mpz_cmpabs_d(context.Args[0], a); }
+ int CompareAbsTo(double a) { IN_CONTEXT(this); return MP(cmpabs_d)(CTXT(0), a); }
/// Calculates the sign (+1, 0, or -1) of the source value.
/// If the source is an expression, it is evaluated into a temporary variable before the sign is computed.
///
/// +1 if the source is positive, -1 if negative, and 0 if zero.
- int Sign() { IN_CONTEXT(this); return mpz_sgn(context.Args[0]); }
+ int Sign() { IN_CONTEXT(this); return MP(sgn)(CTXT(0)); }
#pragma endregion
@@ -1097,7 +831,7 @@ namespace MPIR
///
/// Divisor to test with. This can be zero; only zero is considired divisible by zero.
/// True if the source is evenly divisible by
- bool IsDivisibleBy(IntegerExpression^ a) { IN_CONTEXT(this, a); return mpz_divisible_p(context.Args[0], context.Args[1]) != 0; }
+ bool IsDivisibleBy(MPEXPR_NAME^ a) { IN_CONTEXT(this, a); return MP(divisible_p)(CTXT(0), CTXT(1)) != 0; }
///
/// Checks if the source is evenly divisible by .
@@ -1105,7 +839,7 @@ namespace MPIR
///
/// Divisor to test with. This can be zero; only zero is considired divisible by zero.
/// True if the source is evenly divisible by
- bool IsDivisibleBy(mpir_ui a) { IN_CONTEXT(this); return mpz_divisible_ui_p(context.Args[0], a) != 0; }
+ bool IsDivisibleBy(mpir_ui a) { IN_CONTEXT(this); return MP(divisible_ui_p)(CTXT(0), a) != 0; }
///
/// Checks if the source is evenly divisible by 2^.
@@ -1113,7 +847,7 @@ namespace MPIR
///
/// Power of 2 to use for the divisor
/// True if the source is evenly divisible by 2^
- bool IsDivisibleByPowerOf2(mp_bitcnt_t power) { IN_CONTEXT(this); return mpz_divisible_2exp_p(context.Args[0], power) != 0; }
+ bool IsDivisibleByPowerOf2(mp_bitcnt_t power) { IN_CONTEXT(this); return MP(divisible_2exp_p)(CTXT(0), power) != 0; }
///
/// Checks if the source is congruent to modulo .
@@ -1122,7 +856,7 @@ namespace MPIR
/// Divisor to test with. This can be zero; only zero is considired divisible by zero.
/// Modulo with respect to which to test for congruency
/// True if the source is congruent to modulo
- bool IsCongruentTo(IntegerExpression^ a, IntegerExpression^ mod) { IN_CONTEXT(this, a, mod); return mpz_congruent_p(context.Args[0], context.Args[1], context.Args[2]) != 0; }
+ bool IsCongruentTo(MPEXPR_NAME^ a, MPEXPR_NAME^ mod) { IN_CONTEXT(this, a, mod); return MP(congruent_p)(CTXT(0), CTXT(1), CTXT(2)) != 0; }
///
/// Checks if the source is congruent to modulo .
@@ -1131,7 +865,7 @@ namespace MPIR
/// Divisor to test with. This can be zero; only zero is considired divisible by zero.
/// Modulo with respect to which to test for congruency
/// True if the source is congruent to modulo
- bool IsCongruentTo(mpir_ui a, mpir_ui mod) { IN_CONTEXT(this); return mpz_congruent_ui_p(context.Args[0], a, mod) != 0; }
+ bool IsCongruentTo(mpir_ui a, mpir_ui mod) { IN_CONTEXT(this); return MP(congruent_ui_p)(CTXT(0), a, mod) != 0; }
///
/// Checks if the source is congruent to modulo 2^.
@@ -1140,7 +874,7 @@ namespace MPIR
/// Divisor to test with
/// Power of 2 to use for the modulo
/// True if the source is congruent to modulo 2^
- bool IsCongruentToModPowerOf2(IntegerExpression^ a, mp_bitcnt_t power) { IN_CONTEXT(this, a); return mpz_congruent_2exp_p(context.Args[0], context.Args[1], power) != 0; }
+ bool IsCongruentToModPowerOf2(MPEXPR_NAME^ a, mp_bitcnt_t power) { IN_CONTEXT(this, a); return MP(congruent_2exp_p)(CTXT(0), CTXT(1), power) != 0; }
///
/// Checks if the source is a perfect power.
@@ -1149,7 +883,7 @@ namespace MPIR
/// Negative values are accepted, but of course can only be odd powers.
///
/// True if the source is a perfect power
- bool IsPerfectPower() { IN_CONTEXT(this); return mpz_perfect_power_p(context.Args[0]) != 0; }
+ bool IsPerfectPower() { IN_CONTEXT(this); return MP(perfect_power_p)(CTXT(0)) != 0; }
///
/// Checks if the source is a perfect square.
@@ -1157,7 +891,7 @@ namespace MPIR
/// Both 0 and 1 are considered perfect squares.
///
/// True if the source is a perfect square
- bool IsPerfectSquare() { IN_CONTEXT(this); return mpz_perfect_square_p(context.Args[0]) != 0; }
+ bool IsPerfectSquare() { IN_CONTEXT(this); return MP(perfect_square_p)(CTXT(0)) != 0; }
///
/// Returns the size of the absolute value of the number, measured in number of limbs.
@@ -1165,7 +899,7 @@ namespace MPIR
/// Because this method returns a primitive type, it is computed immediately.
///
/// The number of limbs used to represent the number
- size_t Size() { IN_CONTEXT(this); return mpz_size(context.Args[0]); }
+ size_t Size() { IN_CONTEXT(this); return MP(size)(CTXT(0)); }
#pragma endregion
@@ -1181,7 +915,7 @@ namespace MPIR
///
/// Random number generator to use for probabilistic primality tests
/// An expression object that, when assigned to the Value property or consumed by a primitive-returning method, performs the requested operation
- IntegerExpression^ NextPrimeCandidate(MpirRandom^ random);
+ MPEXPR_NAME^ NextPrimeCandidate(MpirRandom^ random);
/// Computes the greatest common divisor of this number and .
/// The result is always positive even if one or both inputs are negative.
@@ -1189,7 +923,7 @@ namespace MPIR
///
/// Source value to compute the GCD with
/// An expression object that, when assigned to the Value property or consumed by a primitive-returning method, computes the requested operation
- IntegerGcdExpression^ Gcd(IntegerExpression^ a);
+ MPEXPR(Gcd)^ Gcd(MPEXPR_NAME^ a);
///
/// Computes the greatest common divisor of this number and .
@@ -1198,7 +932,7 @@ namespace MPIR
///
/// Source value to compute the GCD with. If zero, zero is returned.
/// The greatest common divisor of the absolute value of this number and .
- mpir_ui Gcd(mpir_ui a) { IN_CONTEXT(this); return mpz_gcd_ui(nullptr, context.Args[0], a); }
+ mpir_ui Gcd(mpir_ui a) { IN_CONTEXT(this); return MP(gcd_ui)(nullptr, CTXT(0), a); }
/// Computes the least common multiple of this number and .
/// The result is always positive, irrespective of the signs of the source numbers.
@@ -1207,7 +941,7 @@ namespace MPIR
///
/// Source value to compute the LCM with.
/// An expression object that, when assigned to the Value property or consumed by a primitive-returning method, computes the requested operation
- IntegerExpression^ Lcm(IntegerExpression^ a);
+ MPEXPR_NAME^ Lcm(MPEXPR_NAME^ a);
/// Computes the least common multiple of this number and .
/// The result is always positive, irrespective of the signs of the source numbers.
@@ -1216,7 +950,7 @@ namespace MPIR
///
/// Source value to compute the LCM with.
/// An expression object that, when assigned to the Value property or consumed by a primitive-returning method, computes the requested operation
- IntegerExpression^ Lcm(mpir_ui a);
+ MPEXPR_NAME^ Lcm(mpir_ui a);
/// Computes the inverse of this number modulo .
/// If the inverse exists, the result will satisfy 0 <= result < .
@@ -1225,7 +959,7 @@ namespace MPIR
///
/// Modulo with respect to which to invert the number.
/// An expression object that, when assigned to the Value property or consumed by a primitive-returning method, computes the requested operation
- IntegerExpression^ Invert(IntegerExpression^ modulo);
+ MPEXPR_NAME^ Invert(MPEXPR_NAME^ modulo);
/// Remove all occurrences of the from the source number.
/// You can optionally save the number of such occurrences that were removed.
@@ -1233,7 +967,7 @@ namespace MPIR
///
/// Factor to remove from the source number.
/// An expression object that, when assigned to the Value property or consumed by a primitive-returning method, computes the requested operation
- IntegerRemoveFactorsExpression^ RemoveFactors(IntegerExpression^ factor);
+ MPEXPR(RemoveFactors)^ RemoveFactors(MPEXPR_NAME^ factor);
#pragma endregion
};
@@ -1251,7 +985,7 @@ namespace MPIR
static int _toStringDigits;
internal:
- static HugeInt^ _toStringModulo;
+ static MPTYPE^ _toStringModulo;
public:
///
@@ -1287,10 +1021,10 @@ namespace MPIR
///
/// Expression that results from a division or modulo operator. Allows to set the rounding mode for the division.
///
- public ref class IntegerDivModExpression abstract : IntegerExpression
+ public ref class MPEXPR(DivMod) abstract : MPEXPR_NAME
{
internal:
- IntegerDivModExpression() { }
+ MPEXPR(DivMod)() { }
RoundingModes rounding;
public:
@@ -1299,7 +1033,7 @@ namespace MPIR
///
/// the mode to use. If this is Default, the static MpirSettings.Rounding mode is used.
/// An updated expression, with its internal state updated to use the specified rounding mode.
- IntegerExpression^ Rounding(RoundingModes mode)
+ MPEXPR_NAME^ Rounding(RoundingModes mode)
{
rounding = mode;
return this;
@@ -1309,12 +1043,12 @@ namespace MPIR
///
/// Expression that results from a division operator. Allows to save the remainder to a separate result object, and/or set the rounding mode for the division.
///
- public ref class IntegerDivideExpression abstract : IntegerDivModExpression
+ public ref class MPEXPR(Divide) abstract : MPEXPR(DivMod)
{
internal:
- IntegerDivideExpression() { }
- HugeInt^ _remainder;
- void custom_mpz_div(mpz_ptr q, mpz_srcptr n, mpz_srcptr d);
+ MPEXPR(Divide)() { }
+ MPTYPE^ _remainder;
+ void CUSTOM_MP(div)(MP(ptr) q, MP(srcptr) n, MP(srcptr) d);
public:
///
@@ -1322,7 +1056,7 @@ namespace MPIR
///
/// destination for the remainder. This cannot be the same object the resulting division quotient is being assigned to.
/// An updated expression, with its internal state updated to compute the remainder.
- IntegerDivModExpression^ SavingRemainderTo(HugeInt^ destination)
+ MPEXPR(DivMod)^ SavingRemainderTo(MPTYPE^ destination)
{
_remainder = destination;
return this;
@@ -1332,14 +1066,14 @@ namespace MPIR
///
/// Expression that results from a division operator. Allows to save the remainder, and/or set the rounding mode for the division.
///
- public ref class IntegerDivideUiExpression abstract : IntegerDivideExpression
+ public ref class MPEXPR(DivideUi) abstract : MPEXPR(Divide)
{
private:
Action^ _limbRemainder;
internal:
- IntegerDivideUiExpression() { }
- void custom_mpz_div_ui(mpz_ptr q, mpz_srcptr n, mpir_ui d);
+ MPEXPR(DivideUi)() { }
+ void CUSTOM_MP(div_ui)(MP(ptr) q, MP(srcptr) n, mpir_ui d);
public:
///
@@ -1348,7 +1082,7 @@ namespace MPIR
/// The delegate that will be called with the remainder of the division.
/// The delegate is called when the division is evaluated, i.e. is assigned to the Value property or consumed by a method that returns a primitive type.
/// An updated expression, with its internal state updated to compute the remainder.
- IntegerDivideExpression^ SettingRemainderTo(Action^ callback)
+ MPEXPR(Divide)^ SettingRemainderTo(Action^ callback)
{
_limbRemainder = callback;
return this;
@@ -1358,12 +1092,12 @@ namespace MPIR
///
/// Expression that results from a modulo operator. Allows to save the division result to a separate object, and/or set the rounding mode for the division.
///
- public ref class IntegerModExpression abstract : IntegerDivModExpression
+ public ref class MPEXPR(Mod) abstract : MPEXPR(DivMod)
{
internal:
- IntegerModExpression() { }
- HugeInt^ _quotient;
- void custom_mpz_mod(mpz_ptr r, mpz_srcptr n, mpz_srcptr d);
+ MPEXPR(Mod)() { }
+ MPTYPE^ _quotient;
+ void CUSTOM_MP(mod)(MP(ptr) r, MP(srcptr) n, MP(srcptr) d);
public:
///
@@ -1371,7 +1105,7 @@ namespace MPIR
///
/// destination for the quotient. This cannot be the same object the resulting division modulo is being assigned to.
/// An updated expression, with its internal state updated to compute the quotient.
- IntegerDivModExpression^ SavingQuotientTo(HugeInt^ destination)
+ MPEXPR(DivMod)^ SavingQuotientTo(MPTYPE^ destination)
{
_quotient = destination;
return this;
@@ -1381,14 +1115,14 @@ namespace MPIR
///
/// Expression that results from a modulo operator. Allows to save the division result to a separate object, and/or set the rounding mode for the division.
///
- public ref class IntegerModUiExpression abstract : IntegerModExpression
+ public ref class MPEXPR(ModUi) abstract : MPEXPR(Mod)
{
private:
Action^ _limbRemainder;
internal:
- IntegerModUiExpression() { }
- void custom_mpz_mod_ui(mpz_ptr r, mpz_srcptr n, mpir_ui d);
+ MPEXPR(ModUi)() { }
+ void CUSTOM_MP(mod_ui)(MP(ptr) r, MP(srcptr) n, mpir_ui d);
public:
///
@@ -1397,7 +1131,7 @@ namespace MPIR
/// The delegate that will be called with the remainder of the division.
/// The delegate is called when the division is evaluated, i.e. is assigned to the Value property or consumed by a method that returns a primitive type.
/// An updated expression, with its internal state updated to compute the remainder.
- IntegerModExpression^ SettingRemainderTo(Action^ callback)
+ MPEXPR(Mod)^ SettingRemainderTo(Action^ callback)
{
_limbRemainder = callback;
return this;
@@ -1407,21 +1141,21 @@ namespace MPIR
///
/// Expression that results from a right shift operator. Allows to save the remainder to a separate result object, and/or set the rounding mode for the division.
///
- public ref class IntegerShiftRightExpression abstract : IntegerDivModExpression
+ public ref class MPEXPR(ShiftRight) abstract : MPEXPR(DivMod)
{
private:
bool _remainder;
internal:
- IntegerShiftRightExpression() { }
- void custom_mpz_div_2exp(mpz_ptr q, mpz_srcptr n, mp_bitcnt_t bits);
+ MPEXPR(ShiftRight)() { }
+ void CUSTOM_MP(div_2exp)(MP(ptr) q, MP(srcptr) n, mp_bitcnt_t bits);
public:
///
/// Computes the remainder of the division, rather than the quotient, which is the default.
///
/// An updated expression, with its internal state updated to compute the remainder, rather than the quotient.
- IntegerDivModExpression^ Remainder()
+ MPEXPR(DivMod)^ Remainder()
{
_remainder = true;
return this;
@@ -1431,12 +1165,12 @@ namespace MPIR
///
/// Expression that results from a square root function. Allows to save the remainder to a separate result object.
///
- public ref class IntegerSquareRootExpression abstract : IntegerExpression
+ public ref class MPEXPR(SquareRoot) abstract : MPEXPR_NAME
{
internal:
- IntegerSquareRootExpression() { }
- HugeInt^ _remainder;
- void custom_mpz_sqrt(mpz_ptr dest, mpz_srcptr oper);
+ MPEXPR(SquareRoot)() { }
+ MPTYPE^ _remainder;
+ void CUSTOM_MP(sqrt)(MP(ptr) dest, MP(srcptr) oper);
public:
///
@@ -1444,7 +1178,7 @@ namespace MPIR
///
/// destination for the remainder. This cannot be the same object the result of the root operation is being assigned to.
/// An updated expression, with its internal state updated to save the remainder.
- IntegerExpression^ SavingRemainderTo(HugeInt^ destination)
+ MPEXPR_NAME^ SavingRemainderTo(MPTYPE^ destination)
{
_remainder = destination;
return this;
@@ -1454,14 +1188,14 @@ namespace MPIR
///
/// Expression that results from a root function. Allows to save a flag indicating whether the root was exact, or to save the remainder to a separate result object.
///
- public ref class IntegerRootExpression abstract : IntegerSquareRootExpression
+ public ref class MPEXPR(Root) abstract : MPEXPR(SquareRoot)
{
private:
Action^ _exact;
internal:
- IntegerRootExpression() { }
- void custom_mpz_root(mpz_ptr dest, mpz_srcptr oper, mpir_ui power);
+ MPEXPR(Root)() { }
+ void CUSTOM_MP(root)(MP(ptr) dest, MP(srcptr) oper, mpir_ui power);
public:
///
@@ -1470,7 +1204,7 @@ namespace MPIR
/// Delegate that will be called with the exact flag.
/// The delegate is called when the root operation is evaluated, i.e. is assigned to the Value property or consumed by a method that returns a primitive type.
/// An updated expression, with its internal state updated to compute the exact flag.
- IntegerExpression^ SettingExactTo(Action^ callback)
+ MPEXPR_NAME^ SettingExactTo(Action^ callback)
{
_exact = callback;
return this;
@@ -1480,13 +1214,13 @@ namespace MPIR
///
/// Expression that results from a Gcd method. Allows to additionally compute Diophantine equation multiplier(s).
///
- public ref class IntegerGcdExpression abstract : IntegerExpression
+ public ref class MPEXPR(Gcd) abstract : MPEXPR_NAME
{
internal:
- IntegerGcdExpression() { }
- HugeInt^ _s;
- HugeInt^ _t;
- void custom_mpz_gcd(mpz_ptr dest, mpz_srcptr a, mpz_srcptr b);
+ MPEXPR(Gcd)() { }
+ MPTYPE^ _s;
+ MPTYPE^ _t;
+ void CUSTOM_MP(gcd)(MP(ptr) dest, MP(srcptr) a, MP(srcptr) b);
public:
///
@@ -1496,7 +1230,7 @@ namespace MPIR
/// destination for the first coefficient. Can be null if not needed.
/// destination for the second coefficient. Can be null if not needed.
/// An updated expression, with its internal state updated to save the coefficients.
- IntegerExpression^ SavingDiophantineMultipliersTo(HugeInt^ s, HugeInt^ t)
+ MPEXPR_NAME^ SavingDiophantineMultipliersTo(MPTYPE^ s, MPTYPE^ t)
{
_s = s;
_t = t;
@@ -1507,10 +1241,10 @@ namespace MPIR
///
/// Expression that results from a RemoveFactors method. Allows to additionally save the number of factors that were removed.
///
- public ref class IntegerRemoveFactorsExpression abstract : IntegerExpression
+ public ref class MPEXPR(RemoveFactors) abstract : MPEXPR_NAME
{
internal:
- IntegerRemoveFactorsExpression() { }
+ MPEXPR(RemoveFactors)() { }
Action^ _count;
public:
@@ -1520,7 +1254,7 @@ namespace MPIR
/// Delegate that will be called with the number of factors that were removed.
/// The delegate is called when the root operation is evaluated, i.e. is assigned to the Value property or consumed by a method that returns a primitive type.
/// An updated expression, with its internal state updated to save the number of factors.
- IntegerExpression^ SavingCountRemovedTo(Action^ callback)
+ MPEXPR_NAME^ SavingCountRemovedTo(Action^ callback)
{
_count = callback;
return this;
@@ -1530,11 +1264,11 @@ namespace MPIR
///
/// Expression that results from a method calculating a single number from a sequence, such as a fibonacci or lucas number. Allows to save the previous number in addition to the requested one, so that the sequence can be continued.
///
- public ref class IntegerSequenceExpression abstract : IntegerExpression
+ public ref class MPEXPR(Sequence) abstract : MPEXPR_NAME
{
internal:
- IntegerSequenceExpression() { }
- HugeInt^ _previous;
+ MPEXPR(Sequence)() { }
+ MPTYPE^ _previous;
public:
///
@@ -1542,7 +1276,7 @@ namespace MPIR
///
/// destination for the previous number. This cannot be the same object to which the expression is assigned.
/// An updated expression, with its internal state updated to additionally compute the previous number.
- IntegerExpression^ SavingPreviousTo(HugeInt^ destination)
+ MPEXPR_NAME^ SavingPreviousTo(MPTYPE^ destination)
{
_previous = destination;
return this;
@@ -1553,64 +1287,64 @@ namespace MPIR
#pragma region concrete expressions
- DEFINE_BINARY_EXPRESSION_WITH_TWO (IntegerExpression, Add, Int)
- DEFINE_BINARY_EXPRESSION_WITH_BUILT_IN_RIGHT (IntegerExpression, Add, Int, Ui)
- DEFINE_BINARY_EXPRESSION_WITH_BUILT_IN_RIGHT (IntegerExpression, Add, Int, Si)
+ DEFINE_BINARY_EXPRESSION_WITH_TWO (MPEXPR_NAME, Add, Int)
+ DEFINE_BINARY_EXPRESSION_WITH_BUILT_IN_RIGHT (MPEXPR_NAME, Add, Int, Ui)
+ DEFINE_BINARY_EXPRESSION_WITH_BUILT_IN_RIGHT (MPEXPR_NAME, Add, Int, Si)
- DEFINE_BINARY_EXPRESSION_WITH_TWO (IntegerExpression, Subtract, Int)
- DEFINE_BINARY_EXPRESSION_WITH_BUILT_IN_RIGHT (IntegerExpression, Subtract, Int, Ui)
- DEFINE_BINARY_EXPRESSION_WITH_BUILT_IN_LEFT (IntegerExpression, Subtract, Ui, Int)
- DEFINE_BINARY_EXPRESSION_WITH_BUILT_IN_RIGHT (IntegerExpression, Subtract, Int, Si)
- DEFINE_BINARY_EXPRESSION_WITH_BUILT_IN_LEFT (IntegerExpression, Subtract, Si, Int)
+ DEFINE_BINARY_EXPRESSION_WITH_TWO (MPEXPR_NAME, Subtract, Int)
+ DEFINE_BINARY_EXPRESSION_WITH_BUILT_IN_RIGHT (MPEXPR_NAME, Subtract, Int, Ui)
+ DEFINE_BINARY_EXPRESSION_WITH_BUILT_IN_LEFT (MPEXPR_NAME, Subtract, Ui, Int)
+ DEFINE_BINARY_EXPRESSION_WITH_BUILT_IN_RIGHT (MPEXPR_NAME, Subtract, Int, Si)
+ DEFINE_BINARY_EXPRESSION_WITH_BUILT_IN_LEFT (MPEXPR_NAME, Subtract, Si, Int)
- DEFINE_BINARY_EXPRESSION_WITH_TWO (IntegerExpression, Multiply, Int)
- DEFINE_BINARY_EXPRESSION_WITH_BUILT_IN_RIGHT (IntegerExpression, Multiply, Int, Ui)
- DEFINE_BINARY_EXPRESSION_WITH_BUILT_IN_RIGHT (IntegerExpression, Multiply, Int, Si)
+ DEFINE_BINARY_EXPRESSION_WITH_TWO (MPEXPR_NAME, Multiply, Int)
+ DEFINE_BINARY_EXPRESSION_WITH_BUILT_IN_RIGHT (MPEXPR_NAME, Multiply, Int, Ui)
+ DEFINE_BINARY_EXPRESSION_WITH_BUILT_IN_RIGHT (MPEXPR_NAME, Multiply, Int, Si)
- DEFINE_BINARY_EXPRESSION_WITH_BUILT_IN_RIGHT (IntegerExpression, ShiftLeft, Int, Bits)
+ DEFINE_BINARY_EXPRESSION_WITH_BUILT_IN_RIGHT (MPEXPR_NAME, ShiftLeft, Int, Bits)
- DEFINE_UNARY_EXPRESSION_WITH_ONE (IntegerExpression, Negate, Int)
- DEFINE_UNARY_EXPRESSION_WITH_ONE (IntegerExpression, Abs, Int)
+ DEFINE_UNARY_EXPRESSION_WITH_ONE (MPEXPR_NAME, Negate, Int)
+ DEFINE_UNARY_EXPRESSION_WITH_ONE (MPEXPR_NAME, Abs, Int)
- DEFINE_BINARY_EXPRESSION_WITH_TWO (IntegerDivideExpression, Divide, Int)
- DEFINE_BINARY_EXPRESSION_WITH_BUILT_IN_RIGHT (IntegerDivideUiExpression, Divide, Int, Ui)
+ DEFINE_BINARY_EXPRESSION_WITH_TWO (MPEXPR(Divide), Divide, Int)
+ DEFINE_BINARY_EXPRESSION_WITH_BUILT_IN_RIGHT (MPEXPR(DivideUi), Divide, Int, Ui)
- DEFINE_BINARY_EXPRESSION_WITH_BUILT_IN_RIGHT (IntegerShiftRightExpression, ShiftRight, Int, Bits)
+ DEFINE_BINARY_EXPRESSION_WITH_BUILT_IN_RIGHT (MPEXPR(ShiftRight), ShiftRight, Int, Bits)
- DEFINE_BINARY_EXPRESSION_WITH_TWO (IntegerModExpression, Mod, Int)
- DEFINE_BINARY_EXPRESSION_WITH_BUILT_IN_RIGHT (IntegerModUiExpression, Mod, Int, Ui)
+ DEFINE_BINARY_EXPRESSION_WITH_TWO (MPEXPR(Mod), Mod, Int)
+ DEFINE_BINARY_EXPRESSION_WITH_BUILT_IN_RIGHT (MPEXPR(ModUi), Mod, Int, Ui)
- DEFINE_BINARY_EXPRESSION_WITH_TWO (IntegerExpression, DivideExactly, Int)
- DEFINE_BINARY_EXPRESSION_WITH_BUILT_IN_RIGHT (IntegerExpression, DivideExactly, Int, Ui)
+ DEFINE_BINARY_EXPRESSION_WITH_TWO (MPEXPR_NAME, DivideExactly, Int)
+ DEFINE_BINARY_EXPRESSION_WITH_BUILT_IN_RIGHT (MPEXPR_NAME, DivideExactly, Int, Ui)
- DEFINE_TERNARY_EXPRESSION_WITH_THREE (IntegerExpression, PowerMod, Int)
- DEFINE_TERNARY_EXPRESSION_WITH_BUILT_IN_MIDDLE (IntegerExpression, PowerMod, Int, Ui, Int)
+ DEFINE_TERNARY_EXPRESSION_WITH_THREE (MPEXPR_NAME, PowerMod, Int)
+ DEFINE_TERNARY_EXPRESSION_WITH_BUILT_IN_MIDDLE (MPEXPR_NAME, PowerMod, Int, Ui, Int)
- DEFINE_BINARY_EXPRESSION_WITH_BUILT_IN_RIGHT (IntegerExpression, Power, Int, Ui)
+ DEFINE_BINARY_EXPRESSION_WITH_BUILT_IN_RIGHT (MPEXPR_NAME, Power, Int, Ui)
- DEFINE_BINARY_EXPRESSION_WITH_BUILT_IN_RIGHT (IntegerRootExpression, Root, Int, Ui)
- DEFINE_UNARY_EXPRESSION_WITH_ONE (IntegerSquareRootExpression, SquareRoot, Int)
+ DEFINE_BINARY_EXPRESSION_WITH_BUILT_IN_RIGHT (MPEXPR(Root), Root, Int, Ui)
+ DEFINE_UNARY_EXPRESSION_WITH_ONE (MPEXPR(SquareRoot), SquareRoot, Int)
- DEFINE_BINARY_EXPRESSION_WITH_TWO (IntegerExpression, And, Int)
- DEFINE_BINARY_EXPRESSION_WITH_TWO (IntegerExpression, Or, Int)
- DEFINE_BINARY_EXPRESSION_WITH_TWO (IntegerExpression, Xor, Int)
- DEFINE_UNARY_EXPRESSION_WITH_ONE (IntegerExpression, Complement, Int)
+ DEFINE_BINARY_EXPRESSION_WITH_TWO (MPEXPR_NAME, And, Int)
+ DEFINE_BINARY_EXPRESSION_WITH_TWO (MPEXPR_NAME, Or, Int)
+ DEFINE_BINARY_EXPRESSION_WITH_TWO (MPEXPR_NAME, Xor, Int)
+ DEFINE_UNARY_EXPRESSION_WITH_ONE (MPEXPR_NAME, Complement, Int)
- DEFINE_BINARY_EXPRESSION_WITH_TWO (IntegerExpression, Invert, Int)
- DEFINE_BINARY_EXPRESSION_WITH_BUILT_IN_RIGHT (IntegerExpression, NextPrimeCandidate, Int, Rnd)
- DEFINE_BINARY_EXPRESSION_WITH_TWO (IntegerGcdExpression, Gcd, Int)
- DEFINE_BINARY_EXPRESSION_WITH_TWO (IntegerRemoveFactorsExpression, RemoveFactors, Int)
+ DEFINE_BINARY_EXPRESSION_WITH_TWO (MPEXPR_NAME, Invert, Int)
+ DEFINE_BINARY_EXPRESSION_WITH_BUILT_IN_RIGHT (MPEXPR_NAME, NextPrimeCandidate, Int, Rnd)
+ DEFINE_BINARY_EXPRESSION_WITH_TWO (MPEXPR(Gcd), Gcd, Int)
+ DEFINE_BINARY_EXPRESSION_WITH_TWO (MPEXPR(RemoveFactors), RemoveFactors, Int)
- DEFINE_BINARY_EXPRESSION_WITH_TWO (IntegerExpression, Lcm, Int)
- DEFINE_BINARY_EXPRESSION_WITH_BUILT_IN_RIGHT (IntegerExpression, Lcm, Int, Ui)
+ DEFINE_BINARY_EXPRESSION_WITH_TWO (MPEXPR_NAME, Lcm, Int)
+ DEFINE_BINARY_EXPRESSION_WITH_BUILT_IN_RIGHT (MPEXPR_NAME, Lcm, Int, Ui)
- DEFINE_BINARY_EXPRESSION_WITH_BUILT_INS_ONLY (IntegerExpression, Power, Ui, Ui)
- DEFINE_BINARY_EXPRESSION_WITH_BUILT_INS_ONLY (IntegerExpression, Factorial, Ui, Ui)
- DEFINE_UNARY_EXPRESSION_WITH_BUILT_INS_ONLY (IntegerExpression, Primorial, Ui)
- DEFINE_BINARY_EXPRESSION_WITH_BUILT_INS_ONLY (IntegerExpression, Binomial, Ui, Ui)
- DEFINE_BINARY_EXPRESSION_WITH_BUILT_IN_RIGHT (IntegerExpression, Binomial, Int, Ui)
- DEFINE_UNARY_EXPRESSION_WITH_BUILT_INS_ONLY (IntegerSequenceExpression, Fibonacci, Ui)
- DEFINE_UNARY_EXPRESSION_WITH_BUILT_INS_ONLY (IntegerSequenceExpression, Lucas, Ui)
+ DEFINE_BINARY_EXPRESSION_WITH_BUILT_INS_ONLY (MPEXPR_NAME, Power, Ui, Ui)
+ DEFINE_BINARY_EXPRESSION_WITH_BUILT_INS_ONLY (MPEXPR_NAME, Factorial, Ui, Ui)
+ DEFINE_UNARY_EXPRESSION_WITH_BUILT_INS_ONLY (MPEXPR_NAME, Primorial, Ui)
+ DEFINE_BINARY_EXPRESSION_WITH_BUILT_INS_ONLY (MPEXPR_NAME, Binomial, Ui, Ui)
+ DEFINE_BINARY_EXPRESSION_WITH_BUILT_IN_RIGHT (MPEXPR_NAME, Binomial, Int, Ui)
+ DEFINE_UNARY_EXPRESSION_WITH_BUILT_INS_ONLY (MPEXPR(Sequence), Fibonacci, Ui)
+ DEFINE_UNARY_EXPRESSION_WITH_BUILT_INS_ONLY (MPEXPR(Sequence), Lucas, Ui)
#pragma endregion
@@ -1619,17 +1353,17 @@ namespace MPIR
///
/// Multi-precision Integer class.
///
- public ref class HugeInt : IntegerExpression
+ public ref class MPTYPE : MPEXPR_NAME
{
internal:
//fields
- mpz_ptr _value;
+ MP(ptr) _value;
private:
//construction
void AllocateStruct()
{
- _value = (mpz_ptr)((*__gmp_allocate_func)(sizeof(__mpz_struct)));
+ _value = (MP(ptr))((*__gmp_allocate_func)(sizeof(MPSTRUCT)));
}
void FromString(String^ value, int base);
String^ ToString(int base, bool lowercase, int maxDigits);
@@ -1637,20 +1371,20 @@ namespace MPIR
internal:
virtual void DeallocateStruct()
{
- mpz_clear(_value);
- (*__gmp_free_func)(_value, sizeof(__mpz_struct));
+ MP(clear)(_value);
+ (*__gmp_free_func)(_value, sizeof(MPSTRUCT));
_value = nullptr;
}
//assignment
- virtual void AssignTo(mpz_ptr destination) override
+ virtual void AssignTo(MP(ptr) destination) override
{
if(destination != _value)
- mpz_set(destination, _value);
+ MP(set)(destination, _value);
}
- virtual void AssignTo(EvaluationContext& destination) override
+ virtual void AssignTo(EvaluationContext& context) override
{
- destination.Args[destination.Index++] = _value;
+ CTXT(context.Index++) = _value;
}
public:
@@ -1659,7 +1393,7 @@ namespace MPIR
///
/// Initializes a new integer instance and sets its value to 0
///
- HugeInt();
+ MPTYPE();
///
/// Initializes a new integer instance, allocating enough memory to hold at least bits, and sets its value to 0.
@@ -1667,14 +1401,14 @@ namespace MPIR
/// This makes it possible to avoid repeated reallocations if a maximum size is known in advance.
///
/// Minimum number of bits the initially allocated memory should hold
- HugeInt(mp_bitcnt_t bits);
+ MPTYPE(mp_bitcnt_t bits);
///
/// Initializes a new integer instance and sets its value from the specified string, using leading characters to recognize the base:
/// 0x and 0X for hexadecimal, 0b and 0B for binary, 0 for octal, or decimal otherwise.
///
/// string representing the initial value for the new instance. Whitespace in the string is ignored.
- HugeInt(String^ value) { FromString(value, 0); }
+ MPTYPE(String^ value) { FromString(value, 0); }
///
/// Initializes a new integer instance and sets its value from the specified string
@@ -1684,41 +1418,41 @@ namespace MPIR
/// The base may vary from 2 to 62, or if base is 0, then the leading characters are used: 0x and 0X for hexadecimal, 0b and 0B for binary, 0 for octal, or decimal otherwise.
/// For bases up to 36, case is ignored; upper-case and lower-case letters have the same value.
/// For bases 37 to 62, upper-case letter represent the usual 10..35 while lower-case letter represent 36..61.
- HugeInt(String^ value, int base) { FromString(value, base); }
+ MPTYPE(String^ value, int base) { FromString(value, base); }
///
/// Initializes a new integer instance and sets its value to the result of computing the source expression.
///
/// the expression that will be computed, and the result set as the initial value of the new instance.
- HugeInt(IntegerExpression^ value);
+ MPTYPE(MPEXPR_NAME^ value);
///
/// Constructs and returns a new integer instance with its value set to the parameter.
///
/// Initial value for the new integer instance
/// the newly constructed instance
- static HugeInt^ FromLong(mpir_si value);
+ static MPTYPE^ FromLong(mpir_si value);
///
/// Constructs and returns a new integer instance with its value set to the parameter.
///
/// Initial value for the new integer instance
/// the newly constructed instance
- static HugeInt^ FromUlong(mpir_ui value);
+ static MPTYPE^ FromUlong(mpir_ui value);
///
/// Constructs and returns a new integer instance with its value set to the parameter.
///
/// Initial value for the new integer instance. Any fractional portion is truncated.
/// the newly constructed instance
- static HugeInt^ FromDouble(double value);
+ static MPTYPE^ FromDouble(double value);
///
/// Change the space allocated for integer to bits. The value in integer is preserved if it fits, or is set to 0 if not.
/// This function can be used to increase the space for a variable in order to avoid repeated automatic reallocations, or to decrease it to give memory back to the heap.
///
/// Minimum number of bits the allocated memory should hold
- void Reallocate(mp_bitcnt_t bits) { mpz_realloc2(_value, bits); }
+ void Reallocate(mp_bitcnt_t bits) { MP(realloc2)(_value, bits); }
//disposal
@@ -1728,13 +1462,13 @@ namespace MPIR
/// Frees all memory allocated by the instance.
/// To minimize memory footprint, multi-precision objects should be disposed of when no longer used, instead of relying on the garbage collector to free the memory.
///
- ~HugeInt() { this->!HugeInt(); }
+ ~MPTYPE() { this->!MPTYPE(); }
///
/// Frees all memory allocated by the instance.
/// To minimize memory footprint, multi-precision objects should be disposed of when no longer used, instead of relying on the garbage collector to free the memory.
///
- !HugeInt() { if(_value != 0) DeallocateStruct(); }
+ !MPTYPE() { if(_value != 0) DeallocateStruct(); }
#pragma endregion
@@ -1775,7 +1509,7 @@ namespace MPIR
/// The sign of the number is ignored, only the absolute value is used.
///
/// The absolute value as a ulong, possibly truncated to the least significant bits only.
- mpir_ui ToUlong() { return mpz_get_ui(_value); }
+ mpir_ui ToUlong() { return MP(get_ui)(_value); }
///
/// Returns the value of the number of the number as a long.
@@ -1783,14 +1517,14 @@ namespace MPIR
/// When truncation occurs, the result is propobly not very useful. Call FitsLong() to check if the number will fit.
///
/// The value as a ulong, possibly truncated to the least significant bits only.
- mpir_si ToLong() { return mpz_get_si(_value); }
+ mpir_si ToLong() { return MP(get_si)(_value); }
///
/// Returns the value of the number of the number as a double, truncating if necessary (rounding towards zero).
/// If the exponent from the conversion is too big, the result is system dependent. An infinity is returned where available.
/// A hardware overflow trap may or may not occur.
///
/// The value as a double, possibly truncated.
- double ToDouble() { return mpz_get_d(_value); }
+ double ToDouble() { return MP(get_d)(_value); }
///
/// Returns the value of the number of the number as a double, truncating if necessary (rounding towards zero), and returning the exponent separately.
@@ -1801,7 +1535,7 @@ namespace MPIR
double ToDouble([Out] mpir_si% exp)
{
mpir_si x;
- auto result = mpz_get_d_2exp(&x, _value);
+ auto result = MP(get_d_2exp)(&x, _value);
exp = x;
return result;
}
@@ -1839,10 +1573,10 @@ namespace MPIR
/// and would not perform as well as doing the same operations on a.Value.
/// It would also not compile if the source were a "using" variable, as all method-local integers should be.
///
- property IntegerExpression^ Value
+ property MPEXPR_NAME^ Value
{
- void set(IntegerExpression^ expr) { expr->AssignTo(_value); }
- IntegerExpression^ get() { return this; }
+ void set(MPEXPR_NAME^ expr) { expr->AssignTo(_value); }
+ MPEXPR_NAME^ get() { return this; }
}
///
@@ -1850,21 +1584,21 @@ namespace MPIR
/// Do not change the value of an object while it is contained in a hash table, because that changes its hash code.
///
/// new value for the object
- void SetTo(mpir_ui value) { mpz_set_ui(_value, value); }
+ void SetTo(mpir_ui value) { MP(set_ui)(_value, value); }
///
/// Sets the value of the integer object.
/// Do not change the value of an object while it is contained in a hash table, because that changes its hash code.
///
/// new value for the object
- void SetTo(mpir_si value) { mpz_set_si(_value, value); }
+ void SetTo(mpir_si value) { MP(set_si)(_value, value); }
///
/// Sets the value of the integer object. Any fractional portion is truncated.
/// Do not change the value of an object while it is contained in a hash table, because that changes its hash code.
///
/// new value for the object
- void SetTo(double value) { mpz_set_d(_value, value); }
+ void SetTo(double value) { MP(set_d)(_value, value); }
///
/// Sets the value of the integer object.
@@ -1891,9 +1625,9 @@ namespace MPIR
/// Do not call this method while either object is contained in a hash table, because this would change their hash codes.
///
/// Source number to swap this instance's value with
- void Swap(HugeInt^ a)
+ void Swap(MPTYPE^ a)
{
- mpz_ptr temp = a->_value;
+ MP(ptr) temp = a->_value;
a->_value = _value;
_value = temp;
}
@@ -1909,7 +1643,7 @@ namespace MPIR
/// Position of the bit to set.
/// The least significant bit is zero.
/// If position is beyond the current size of the number, the number is extended automatically.
- void SetBit(mp_bitcnt_t position, bool value) { value ? mpz_setbit(_value, position) : mpz_clrbit(_value, position); }
+ void SetBit(mp_bitcnt_t position, bool value) { value ? MP(setbit)(_value, position) : MP(clrbit)(_value, position); }
///
/// Gets a single bit at the specified position.
@@ -1919,7 +1653,7 @@ namespace MPIR
/// If position is beyond the current size of the number, returns true for negative number, false for non-negative; the number itself is not extended.
/// true if the specified bit is 1, false if zero.
/// If position is beyond the current size of the number, returns true for negative number, false for non-negative; the number itself is not extended.
- bool GetBit(mp_bitcnt_t position) { return mpz_tstbit(_value, position) != 0; }
+ bool GetBit(mp_bitcnt_t position) { return MP(tstbit)(_value, position) != 0; }
///
/// Complements (inverts) a single bit at the specified position.
@@ -1927,7 +1661,7 @@ namespace MPIR
/// Position of the bit to flip.
/// The least significant bit is zero.
/// If position is beyond the current size of the number, the number is extended automatically.
- void ComplementBit(mp_bitcnt_t position) { mpz_combit(_value, position); }
+ void ComplementBit(mp_bitcnt_t position) { MP(combit)(_value, position); }
#pragma endregion
@@ -1937,37 +1671,37 @@ namespace MPIR
/// Returns true if the value of the integer is in the ulong range.
///
/// true if the value will fit in a ulong
- bool FitsUlong() { return mpz_fits_ui_p(_value) != 0; }
+ bool FitsUlong() { return MP(fits_ui_p)(_value) != 0; }
///
/// Returns true if the value of the integer is in the long range.
///
/// true if the value will fit in a long
- bool FitsLong() { return mpz_fits_si_p(_value) != 0; }
+ bool FitsLong() { return MP(fits_si_p)(_value) != 0; }
///
/// Returns true if the value of the integer is in the uint range.
///
/// true if the value will fit in a uint
- bool FitsUint() { return mpz_fits_uint_p(_value) != 0; }
+ bool FitsUint() { return MP(fits_uint_p)(_value) != 0; }
///
/// Returns true if the value of the integer is in the int range.
///
/// true if the value will fit in a int
- bool FitsInt() { return mpz_fits_sint_p(_value) != 0; }
+ bool FitsInt() { return MP(fits_sint_p)(_value) != 0; }
///
/// Returns true if the value of the integer is in the ushort range.
///
/// true if the value will fit in a ushort
- bool FitsUshort() { return mpz_fits_ushort_p(_value) != 0; }
+ bool FitsUshort() { return MP(fits_ushort_p)(_value) != 0; }
///
/// Returns true if the value of the integer is in the short range.
///
/// true if the value will fit in a short
- bool FitsShort() { return mpz_fits_sshort_p(_value) != 0; }
+ bool FitsShort() { return MP(fits_sshort_p)(_value) != 0; }
///
/// Returns the number of digits the number would take if written in the specified base.
@@ -1983,7 +1717,7 @@ namespace MPIR
///
/// Numeric base for the would-be string conversion, in the range from 2 to 62.
/// The number of digits the number would take written in the specified base, possibly 1 too big, not counting a leading minus.
- mp_size_t ApproximateSizeInBase(int base) { return mpz_sizeinbase(_value, base); }
+ mp_size_t ApproximateSizeInBase(int base) { return MP(sizeinbase)(_value, base); }
#pragma endregion
@@ -1994,7 +1728,7 @@ namespace MPIR
/// The number is written in a portable format, with 4 bytes of size information, and that many bytes of limbs.
/// Both the size and the limbs are written in decreasing significance order (i.e., in big-endian).
/// The output can be read with Read(Stream).
- /// The output cannot be read by mpz_inp_raw from GMP 1, because of changes necessary
+ /// The output cannot be read by MP(inp_raw) from GMP 1, because of changes necessary
/// for compatibility between 32-bit and 64-bit machines.
///
/// Stream to output the number to
@@ -2005,7 +1739,7 @@ namespace MPIR
/// Reads the integer value from the in raw binary format, as it would have been written by Write(Stream).
/// The number is read in a portable format, with 4 bytes of size information, and that many bytes of limbs.
/// Both the size and the limbs are written in decreasing significance order (i.e., in big-endian).
- /// This routine can read the output from mpz_out_raw also from GMP 1, in spite of changes
+ /// This routine can read the output from MP(out_raw) also from GMP 1, in spite of changes
/// necessary for compatibility between 32-bit and 64-bit machines.
///
/// Stream to input the number from
@@ -2094,12 +1828,12 @@ namespace MPIR
{
if(limbCount == 0)
{
- mpz_set_ui(_value, 0);
+ MP(set_ui)(_value, 0);
return;
}
PIN(data);
- mpz_import(_value, limbCount, (int)limbOrder, bytesPerLimb, (int)endianness, nails, pinned_data);
+ MP(import)(_value, limbCount, (int)limbOrder, bytesPerLimb, (int)endianness, nails, pinned_data);
}
///
@@ -2121,7 +1855,7 @@ namespace MPIR
{
PIN(data);
size_t limbCount;
- mpz_export(pinned_data, &limbCount, (int)limbOrder, bytesPerLimb, (int)endianness, nails, _value);
+ MP(export)(pinned_data, &limbCount, (int)limbOrder, bytesPerLimb, (int)endianness, nails, _value);
return limbCount;
}
@@ -2143,12 +1877,12 @@ namespace MPIR
return gcnew array(0);
auto bitsPerLimb = 8 * bytesPerLimb - nails;
- auto limbCount = (mpz_sizeinbase(_value, 2) - 1) / bitsPerLimb + 1;
+ auto limbCount = (MP(sizeinbase)(_value, 2) - 1) / bitsPerLimb + 1;
auto arrayCount = (limbCount * bytesPerLimb - 1) / sizeof(T) + 1;
auto data = gcnew array(arrayCount);
PIN(data);
- mpz_export(pinned_data, &limbCount, (int)limbOrder, bytesPerLimb, (int)endianness, nails, _value);
+ MP(export)(pinned_data, &limbCount, (int)limbOrder, bytesPerLimb, (int)endianness, nails, _value);
return data;
}
@@ -2166,7 +1900,7 @@ namespace MPIR
/// The least significant limb is zero.
/// If the index is outside the range 0 to Size()-1, zero is returned.
/// The specified limb, or zero if is outside of the valid range.
- size_t GetLimb(mp_size_t index) { return mpz_getlimbn(_value, index); }
+ size_t GetLimb(mp_size_t index) { return MP(getlimbn)(_value, index); }
#pragma endregion
@@ -2207,7 +1941,7 @@ namespace MPIR
/// First source value for the Jacobi symbol
/// Second source value for the Jacobi symbol
/// The Jacobi symbol (-1, 0, or 1). Return is undefined unless is odd.
- static int Jacobi(HugeInt^ a, HugeInt^ b) { return mpz_jacobi(a->_value, b->_value); }
+ static int Jacobi(MPTYPE^ a, MPTYPE^ b) { return MP(jacobi)(a->_value, b->_value); }
///
/// Calculates the Legendre symbol (/).
@@ -2216,7 +1950,7 @@ namespace MPIR
/// First source value for the Legendre symbol
/// Second source value for the Legendre symbol
/// The Legendre symbol (-1, 0, or 1). Return is undefined unless is an odd prime.
- static int Legendre(HugeInt^ a, HugeInt^ b) { return mpz_legendre(a->_value, b->_value); }
+ static int Legendre(MPTYPE^ a, MPTYPE^ b) { return MP(legendre)(a->_value, b->_value); }
///
/// Calculates the Jacobi symbol (/) with the Kronecker extension
@@ -2227,7 +1961,7 @@ namespace MPIR
/// First source value for the Kronecker symbol
/// Second source value for the Kronecker symbol
/// The Kronecker symbol (-1, 0, or 1).
- static int Kronecker(HugeInt^ a, HugeInt^ b) { return mpz_kronecker(a->_value, b->_value); }
+ static int Kronecker(MPTYPE^ a, MPTYPE^ b) { return MP(kronecker)(a->_value, b->_value); }
///
/// Calculates the Jacobi symbol (/) with the Kronecker extension
@@ -2238,7 +1972,7 @@ namespace MPIR
/// First source value for the Kronecker symbol
/// Second source value for the Kronecker symbol
/// The Kronecker symbol (-1, 0, or 1).
- static int Kronecker(HugeInt^ a, mpir_ui b) { return mpz_kronecker_ui(a->_value, b); }
+ static int Kronecker(MPTYPE^ a, mpir_ui b) { return MP(kronecker_ui)(a->_value, b); }
///
/// Calculates the Jacobi symbol (/) with the Kronecker extension
@@ -2249,7 +1983,7 @@ namespace MPIR
/// First source value for the Kronecker symbol
/// Second source value for the Kronecker symbol
/// The Kronecker symbol (-1, 0, or 1).
- static int Kronecker(HugeInt^ a, mpir_si b) { return mpz_kronecker_si(a->_value, b); }
+ static int Kronecker(MPTYPE^ a, mpir_si b) { return MP(kronecker_si)(a->_value, b); }
///
/// Calculates the Jacobi symbol (/) with the Kronecker extension
@@ -2260,7 +1994,7 @@ namespace MPIR
/// First source value for the Kronecker symbol
/// Second source value for the Kronecker symbol
/// The Kronecker symbol (-1, 0, or 1).
- static int Kronecker(mpir_ui a, HugeInt^ b) { return mpz_ui_kronecker(a, b->_value); }
+ static int Kronecker(mpir_ui a, MPTYPE^ b) { return MP(ui_kronecker)(a, b->_value); }
///
/// Calculates the Jacobi symbol (/) with the Kronecker extension
@@ -2271,7 +2005,7 @@ namespace MPIR
/// First source value for the Kronecker symbol
/// Second source value for the Kronecker symbol
/// The Kronecker symbol (-1, 0, or 1).
- static int Kronecker(mpir_si a, HugeInt^ b) { return mpz_si_kronecker(a, b->_value); }
+ static int Kronecker(mpir_si a, MPTYPE^ b) { return MP(si_kronecker)(a, b->_value); }
///
/// Returns an expression for calculating raised to the specified .
@@ -2280,7 +2014,7 @@ namespace MPIR
/// Base for the initial value for the new integer instance
/// Power to raise the to when calculating the initial value for the new instance
/// An expression object that, when assigned to the Value property or consumed by a primitive-returning method, computes the requested operation
- static IntegerExpression^ Power(mpir_ui value, mpir_ui power) { return gcnew MpirPowerUiUiExpression(value, power); }
+ static MPEXPR_NAME^ Power(mpir_ui value, mpir_ui power) { return gcnew MPEXPR(PowerUiUi)(value, power); }
///
/// Returns an expression for calculating the factorial of .
@@ -2288,7 +2022,7 @@ namespace MPIR
///
/// The source number to take the factorial of
/// An expression object that, when assigned to the Value property or consumed by a primitive-returning method, computes the requested operation
- static IntegerExpression^ Factorial(mpir_ui a) { return gcnew MpirFactorialUiUiExpression(a, 1); }
+ static MPEXPR_NAME^ Factorial(mpir_ui a) { return gcnew MPEXPR(FactorialUiUi)(a, 1); }
///
/// Returns an expression for calculating the multifactorial of of the specified order.
@@ -2297,7 +2031,7 @@ namespace MPIR
/// The source number to take the multifactorial of
/// The order of the multifactorial, i.e. 2 for !!, 3 for !!!, etc.
/// An expression object that, when assigned to the Value property or consumed by a primitive-returning method, computes the requested operation
- static IntegerExpression^ Factorial(mpir_ui a, mpir_ui order) { return gcnew MpirFactorialUiUiExpression(a, order); }
+ static MPEXPR_NAME^ Factorial(mpir_ui a, mpir_ui order) { return gcnew MPEXPR(FactorialUiUi)(a, order); }
///
/// Returns an expression for calculating the primorial of , i.e. the product of all positive prime numbers <= a.
@@ -2305,7 +2039,7 @@ namespace MPIR
///
/// The source number to take the primorial of
/// An expression object that, when assigned to the Value property or consumed by a primitive-returning method, computes the requested operation
- static IntegerExpression^ Primorial(mpir_ui a) { return gcnew MpirPrimorialUiExpression(a); }
+ static MPEXPR_NAME^ Primorial(mpir_ui a) { return gcnew MPEXPR(PrimorialUi)(a); }
///
/// Returns an expression for calculating the binomial coefficient (, ), a.k.a. number of k-element combinations out of an n-element set.
@@ -2314,7 +2048,7 @@ namespace MPIR
/// The first source value of the binomial coefficient, a.k.a. set size
/// The second source value of the binomial coefficient, a.k.a. subset size
/// An expression object that, when assigned to the Value property or consumed by a primitive-returning method, computes the requested operation
- static IntegerExpression^ Binomial(mpir_ui n, mpir_ui k) { return gcnew MpirBinomialUiUiExpression(n, k); }
+ static MPEXPR_NAME^ Binomial(mpir_ui n, mpir_ui k) { return gcnew MPEXPR(BinomialUiUi)(n, k); }
///
/// Returns an expression for calculating the binomial coefficient (, ), a.k.a. number of k-element combinations out of an n-element set.
@@ -2326,7 +2060,7 @@ namespace MPIR
///
/// The second source value of the binomial coefficient, a.k.a. subset size
/// An expression object that, when assigned to the Value property or consumed by a primitive-returning method, computes the requested operation
- static IntegerExpression^ Binomial(IntegerExpression^ n, mpir_ui k) { return gcnew MpirBinomialIntUiExpression(n, k); }
+ static MPEXPR_NAME^ Binomial(MPEXPR_NAME^ n, mpir_ui k) { return gcnew MPEXPR(BinomialIntUi)(n, k); }
///
/// Returns an expression for calculating the th Fibonacci number.
@@ -2339,7 +2073,7 @@ namespace MPIR
///
/// The index of the Fibonacci number to calculate
/// An expression object that, when assigned to the Value property or consumed by a primitive-returning method, computes the requested operation
- static IntegerSequenceExpression^ Fibonacci(mpir_ui n) { return gcnew MpirFibonacciUiExpression(n); }
+ static MPEXPR(Sequence)^ Fibonacci(mpir_ui n) { return gcnew MPEXPR(FibonacciUi)(n); }
///
/// Returns an expression for calculating the th Lucas number.
@@ -2352,7 +2086,7 @@ namespace MPIR
///
/// The index of the Lucas number to calculate
/// An expression object that, when assigned to the Value property or consumed by a primitive-returning method, computes the requested operation
- static IntegerSequenceExpression^ Lucas(mpir_ui n) { return gcnew MpirLucasUiExpression(n); }
+ static MPEXPR(Sequence)^ Lucas(mpir_ui n) { return gcnew MPEXPR(LucasUi)(n); }
#pragma endregion
};
diff --git a/mpir.net/mpir.net/Random.cpp b/mpir.net/mpir.net/Random.cpp
index 0aea0d4d..8f30a77a 100644
--- a/mpir.net/mpir.net/Random.cpp
+++ b/mpir.net/mpir.net/Random.cpp
@@ -18,6 +18,7 @@ along with the MPIR Library. If not, see http://www.gnu.org/licenses/.
*/
#include "StdAfx.h"
+#include "HugeInt.h"
#include "Random.h"
namespace MPIR
@@ -25,7 +26,7 @@ namespace MPIR
DEFINE_ASSIGNMENT_PROLOG(RandomInt)
{
IN_CONTEXT(Right);
- mpz_urandomm(destination, Left->_value, context.Args[0]);
+ mpz_urandomm(destination, Left->_value, context.IntArgs[0]);
}
DEFINE_ASSIGNMENT_PROLOG(RandomIntBits)
diff --git a/mpir.net/mpir.net/Random.h b/mpir.net/mpir.net/Random.h
index dd9bbdda..03562570 100644
--- a/mpir.net/mpir.net/Random.h
+++ b/mpir.net/mpir.net/Random.h
@@ -216,7 +216,7 @@ namespace MPIR
///
/// number of bits to generate
/// An expression object that, when assigned to the Value property or consumed by a primitive-returning method, generates the random number
- IntegerExpression^ GetIntBits(mp_bitcnt_t bitCount) { return gcnew MpirRandomIntBitsExpression(this, bitCount); }
+ IntegerExpression^ GetIntBits(mp_bitcnt_t bitCount) { return gcnew IntegerRandomIntBitsExpression(this, bitCount); }
///
/// Generates a random integer with long strings of zeros and ones in the binary representation.
@@ -227,7 +227,7 @@ namespace MPIR
///
/// number of bits to generate
/// An expression object that, when assigned to the Value property or consumed by a primitive-returning method, generates the random number
- IntegerExpression^ GetIntBitsChunky(mp_bitcnt_t bitCount) { return gcnew MpirRandomIntBitsChunkyExpression(this, bitCount); }
+ IntegerExpression^ GetIntBitsChunky(mp_bitcnt_t bitCount) { return gcnew IntegerRandomIntBitsChunkyExpression(this, bitCount); }
///
/// Generates a uniformly distributed random integer in the range 0 to - 1, inclusive.
@@ -235,7 +235,7 @@ namespace MPIR
///
/// exclusive upper bound for the number to generate
/// An expression object that, when assigned to the Value property or consumed by a primitive-returning method, generates the random number
- IntegerExpression^ GetInt(IntegerExpression^ max) { return gcnew MpirRandomIntExpression(this, max); }
+ IntegerExpression^ GetInt(IntegerExpression^ max) { return gcnew IntegerRandomIntExpression(this, max); }
#pragma endregion
};
diff --git a/mpir.net/mpir.net/Stdafx.h b/mpir.net/mpir.net/Stdafx.h
index 5398e387..ea5a5487 100644
--- a/mpir.net/mpir.net/Stdafx.h
+++ b/mpir.net/mpir.net/Stdafx.h
@@ -26,4 +26,3 @@ along with the MPIR Library. If not, see http://www.gnu.org/licenses/.
#include "mpir.h"
#include "gmp-impl.h"
#include "Common.h"
-#include "HugeInt.h"