From 6e4af8e1768e6e7104f75c133aa3dbab07b76336 Mon Sep 17 00:00:00 2001 From: Alex Dyachenko Date: Sat, 10 May 2014 15:30:45 -0400 Subject: [PATCH] Major refactoring in preparation for adding the rational class. Broken build due to partial commit. --- build.vc11/mpir.net/mpir.net/mpir.net.vcxproj | 4 +- .../mpir.net/mpir.net.vcxproj.filters | 8 +- .../mpir.net-tests/Utilities/Accessors.cs | 154 +++- mpir.net/mpir.net/Common.h | 206 +++-- mpir.net/mpir.net/ExpressionMacros.h | 259 ++++++ mpir.net/mpir.net/HugeInt.cpp | 356 ++++---- mpir.net/mpir.net/HugeInt.h | 862 ++++++------------ mpir.net/mpir.net/Random.cpp | 3 +- mpir.net/mpir.net/Random.h | 6 +- mpir.net/mpir.net/Stdafx.h | 1 - 10 files changed, 1014 insertions(+), 845 deletions(-) create mode 100644 mpir.net/mpir.net/ExpressionMacros.h 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"