diff --git a/doc/mpir.texi b/doc/mpir.texi index 86f4c10e..9f244cd2 100644 --- a/doc/mpir.texi +++ b/doc/mpir.texi @@ -139,6 +139,7 @@ How to install and use the MPIR multiple precision arithmetic library, version @ * Formatted Output:: @code{printf} style output. * Formatted Input:: @code{scanf} style input. * C++ Class Interface:: Class wrappers around MPIR types. +* .Net Interface:: Managed .Net wrappers for MPIR types. * Custom Allocation:: How to customize the internal allocation. * Language Bindings:: Using MPIR from other languages. * Algorithms:: What happens behind the scenes. @@ -6267,7 +6268,7 @@ results. For classes with overloading, see @ref{C++ Class Interface}. -@node C++ Class Interface, Custom Allocation, Formatted Input, Top +@node C++ Class Interface, .Net Interface, Formatted Input, Top @chapter C++ Class Interface @cindex C++ interface @@ -6853,7 +6854,622 @@ void fun (T f, T g) @end example @end table -@node Custom Allocation, Language Bindings, C++ Class Interface, Top +@node .Net Interface, Custom Allocation, C++ Class Interface, Top +@comment node-name, next, previous, up +@chapter .Net Interface +@cindex .Net Interface +@cindex Microsoft.Net +@cindex Managed Interface + +This chapter describes the Microsoft.Net wrapper around MPIR. + +If you are a .Net developer on MS Windows, using MPIR is possible +via the basic managed-to-native interop tooling provided by .Net. +While this would allow access to the full MPIR intreface, +you would essentially be embedding C code inside whatever .Net language you are using. +This would virtually require familiarity with C/C++, +the interop artefacts in your code would be distractingly evident, +and it would be hard to maintain a smooth code style around managed/native transitions. + +MPIR offers an alternative that addresses these issues: @strong{MPIR.Net}. +MPIR.Net is a Microsoft Visual Studio solution that interoperates with MPIR +and exposes a full managed interface built from scratch, for consumption in any .Net language. +It internalizes all C-rooted idiosynchrasies and allows you to work with MPIR objects +through managed classes that perform all necessary marshaling behind the scenes. +It strives to provide maximum performance by implementing MPIR operations +with direct calls to the native routines while not requiring +you to sacrifice any of your code style. It eliminates any requirement of fluency in C, +yet delivers the performance of native MPIR. In fact, it can consume any native MPIR build, +including all supported processor-specific builds, and can thus take advantage of the +entire wealth of assembly-optimized MPIR routines. + +MPIR.Net is, however, limited to MS Windows and Visual Studio at this time. The managed +interface is written in Microsoft C++/CLI, which ties you to that specific environment. +If you use .Net on Linux and use a compiler other than Visual Studio, MPIR.Net will not +work for you, but then again, you may already have better native interop facilities +available to you than your Windows colleagues, making MPIR.Net rather moot. + +MPIR.Net is bundled with MPIR as an optional feature. To build it, you still +need to build the native MPIR library first. As you do, you can select the best +processor architecture that matches your requirements. Then you build MPIR.Net, and it +is linked statically to the native MPIR library, producing a managed assembly. +Thus, to build MPIR.Net, you need to be familiar with the MPIR build process on Windows, +and have a recent version of Visual Studio available (a community edition will suffice). + +@menu +* MPIR.Net Feature Overview:: +* Building MPIR.Net:: +* MPIR.Net Integers:: +* MPIR.Net Rationals:: +* MPIR.Net Floats:: +* MPIR.Net Random Numbers:: +* MPIR.Net Limitations:: +@end menu + +@node MPIR.Net Feature Overview, Building MPIR.Net, .Net Interface, .Net Interface +@section MPIR.Net Feature Overview + +@noindent +MPIR.Net exposes the following main classes: + +@deftp Class HugeInt +@deftpx Class HugeRational +@deftpx Class HugeFloat +@end deftp + +The standard operators are overloaded to allow arithmetic with these classes. For example, + +@example +void Calculate() +@{ + using (var a = new HugeInt(1234)) + using (var b = new HugeInt("-5678")) + using (var c = new HugeInt(a + b)) + @{ + Debug.WriteLine("Result: @{0@}", c); + @} +@} +@end example + +MPIR.Net's multi-precision classes implement @code{IDisposable}, and the recommended usage +for local instances is as shown above, within a @code{using} clause +to guarantee native memory clean-up when a variable is disposed. + +References that go out of scope without having been disposed are subject to the normal +.Net garbage collection, which in most cases invokes object destructors, which +deallocate native memory. Applications that don't have memory pressure should +work just fine either way, although deterministic disposal is a best practice. + +Like MPIR's native @ref{C++ Class Interface}, MPIR.Net implements an expression like +@code{a.Value = b + c} with a single call to the corresponding native @code{mpz_add}, +without using a temporary for the @code{b + c} part. More complex expressions that do not have +a single-call native implementation like @code{a.Value = b*c + d*e}, still use temporary variables. +Importantly, @code{a.Value = a + b*c} and the like will utilize the native @code{mpz_addmul}, etc. +Note that in all of the above cases the assignment syntax is to set the @code{Value} property; more on that below. + +Another similarity of MPIR.Net with the C++ interface is the deferral of evaluation. +All arithmetic operations and many methods produce an expression object rather than an immediate result. +This allows expressions of arbitrary complexity to be built. They are not evaluated until the expression +is assigned to a destination variable, or when calling a method that produces a primitive (non-MPIR.Net type) result. For example: + +@example +void Calculate() +@{ + var a = new HugeInt(12345); + var b = new HugeInt(67890); + var sum = a + b; // produces an expression + var doubleSum = sum * 2; // produces a new expression + bool positive = doubleSum > 0; // evaluates the doubleSum expression + int sumSign = doubleSum.Sign(); // evaluates the doubleSum expression + a.Value = doubleSum - 4; // evaluates the doubleSum expression +@} +@end example + +Here the addition and multiplication in @code{(a + b) * 2} are computed three times +because they are part of an expression that is consumed +by three destinations, @code{positive}, @code{sumSign}, and @code{a}. +To avoid the triple addition, this method should be re-written as: + +@example +void Calculate() +@{ + var a = new HugeInt(12345); + var b = new HugeInt(67890); + var sum = a + b; // produces an expression + var doubleSum = new HugeInt(sum * 2); // evaluates the expression + bool positive = doubleSum > 0; // evaluates the > comparison + int sumSign = doubleSum.Sign(); // computes the sign + a.Value = doubleSum - 4; // computes the subtraction +@} +@end example + +Now the result of @code{(a + b) * 2} is computed once and stored in an intermediate variable, +whose value is used in subsequent statements. +This code can be shortened as follows without changing the internal calculation: + +@example +void Calculate() +@{ + var a = new HugeInt(12345); + var b = new HugeInt(67890); + var doubleSum = new HugeInt((a + b) * 2); // evaluates the expression + var positive = doubleSum > 0; // evaluates the > comparison + var sumSign = doubleSum.Sign(); // computes the sign + a.Value = doubleSum - 4; // computes the subtraction +@} +@end example + +The main idiosyncrasy of MPIR.Net is its assignment pattern. +MPIR.Net types are implemented as reference types with value semantics. +Like .Net Strings, the objects themselves are just lightweight pointers to data allocated elsewhere. +In this case, the data is in native memory. +Unlike Strings, MPIR types are mutable. + +Value semantics requires you to be able to code statements like @code{a = b + c}. +However, .Net (outside of C++) does not allow overloading the assignment operator, +while assigning references would necessitate some unnecessary duplication and extra memory allocations, +require reliance on the garbage collector, and prevent the use of @code{mpz_addmul} and the like. + +To solve this problem, MPIR.Net uses the property assignment. +All MPIR.Net types have a @code{Value} property. +The magic of this property is in its setter, which does what an overloaded assignment operator would do in C++. +So you write @code{a.Value = b + c} to calculate the sum of @code{b} and @code{c} and store the result in the existing variable @code{a}. +This seems to be as close to an overloaded assignment as you can get in .Net, but is fluent enough to become a quick habit, +and additionally reinforces the concept that an existing object can change its value while reusing internally allocated memory. + +Setting @code{Value} evaluates the expression being assigned. Since at this point the destination is known, +@code{mpz_addmul} and similar can be recognized and invoked. + +Reading this property is less interesting, +as it's equivalent to but wordier than using the reference itself, i.e. @code{a + b} is equivalent to @code{a.Value + b.Value}. +However it is still useful for making possible constructs such as @code{a.Value += 5}, @code{a.Value *= 10}, etc. + +If you absent-mindedly type @code{a = b + c} or @code{a *= 10}, these will not compile +because there is no implicit conversion from an expression. +If an implicit conversion were defined, such code would incur an extra allocation plus garbage collection, +making it potentially slower than performing the same operations on @code{a.Value}. +It would also not compile if the destination were a local variable defined in a @code{using} clause, +as is the recommended practice for method-local instances. + +Care should be taken with the construct @code{var a = b;}. While perfectly legal (and cannot be made otherwise) in .Net, +this only creates a copy of the managed reference to the same MPIR.Net object, without any copying of the data. +If @code{b} is subsequently disposed, referencing @code{a} will throw an error. + +MPIR classes can be intermixed in expressions to some degree. For example, most arithmetic operations with +rational operands will accept integers. Where mixed operations are defined in MPIR, they are also implemented in MPIR.Net. +Floats, on the other hand, typically don't accept operands of other types. There is some cost associated with +creating a floating point instance out of an integer, which would not be evident if automatic promotion existed. +Use explicit constructors to convert instances of one type to new instances of other types, +or one of the @code{SetTo()} overloads to save the result into an existing instance. + +MPIR classes can also be intermixed in expressions with primitive types. For 64-bit builds, this includes +@code{long} and @code{ulong}, which correspond to an MPIR limb. For 32-bit builds, @code{int} and @code{uint} +are the largest primitive types you can use. Smaller integer primitives can always be used because they will be promoted by .Net. + +Conversions back from MPIR classes to primitive types aren't done automatically, +instead methods @code{ToLong()}/{@code{ToUlong()} for 64-bit builds or @code{ToInt()}/@code{ToUint()} are provided. +Integers also implement @code{GetLimb()}. + +@node Building MPIR.Net, MPIR.Net Integers, MPIR.Net Feature Overview, .Net Interface +@section Building MPIR.Net + +To build MPIR.Net, follow the steps below: + +@enumerate +@item +Get the sources + +@item +Build MPIR + +@item +Run MPIR unit tests + +@item +Build MPIR.Net + +@item +Run MPIR.Net unit tests + +@item +Reference MPIR.Net in your managed project +@end enumerate + +@strong{Get the sources}: Clone the MPIR repository on GitHub to get the latest stable MPIR release. +This repository includes MPIR.Net. +Or you can clone the MPIR.Net fork, which will get you the development repository. + +@strong{Build MPIR}: Once you have the sources, you will need to build MPIR first. +Read the MPIR manual, available as a Documentation link on the MPIR page, for full details. +Since MPIR.Net currently requires Windows, you will need to build MPIR for Windows using Microsoft Visual Studio. +MPIR provides solutions for the three latest versions of Visual Studio, and includes full build instructions. +You can select either a generic C build or an optimized build for a specific processor. +You must also select the Windows architecture desired (32-bit or 64-bit), and build configuration (debug/release). +You will need to build MPIR as Lib, not DLL, to use it with MPIR.Net. + +@strong{Run MPIR unit tests}: MPIR contains a full suite of unit tests that you can (and should) execute to validate your build. +It is a large and complex project, and many things can go wrong while building from sources. +Building and running the tests only takes a few of minutes and might save you a lot of headache. +Note that you must also build MPIR's C++ interface to run unit tests, however it is not a dependency for MPIR.Net. + +@strong{Build MPIR.Net}: Next, load the MPIR.Net solution in Visual Studio. +It is located in the MPIR.Net folder, under which there are folders for the different supported Visual Studio versions. +The projects are set up to look for the previously built MPIR library in its normal location in the Lib folder. +You will need to select the same architecture (x64 or x86) and configuration (debug/release) as when you built MPIR. +Then simply build the solution, and you are good to go. + +@strong{Run MPIR.Net unit tests}: MPIR.Net includes its own suite of unit tests. +Because MPIR.Net is a wrapper around MPIR, these tests simply ensure that the right routines in MPIR are being called, +but do not validate the robustness of the MPIR build itself. +Thus, it is necessary to run both MPIR tests and MPIR.Net tests. +MPIR.Net tests, though, are easier to run because they are included right in the MPIR.Net solution. + +Through binary compatibility with GMP 5.x, MPIR 2.x inherits a known issue that causes a few +MPIR.Net tests (2 for x86, 3 for x64) to fail. The issue has been corrected in GMP 6.x, and is expected to be +corrected correspondingly in MPIR 3.x. Because this behavior is not intuitive, +these tests remain in their current failing state until this is resolved. + +@strong{Reference MPIR.Net}: With the MPIR.Net assembly built, you're ready to create your own project +in a .Net language of your choice, add a reference to MPIR.Net, and take advantage of the great mathematical powers of MPIR! + +@node MPIR.Net Integers, MPIR.Net Rationals, Building MPIR.Net, .Net Interface +@section MPIR.Net Integers + +The MPIR.Net type for the MPIR multi-precision integer is @code{HugeInt}. +A closely related type is @code{IntegerExpression}, which is returned from all operators and methods whose +value semantics are to compute another number from the source instance and any arguments. +@code{HugeInt} derives from @code{IntegerExpression}, and many operations are defined on the expression class. +Operations defined on @code{HugeInt} but not on @code{IntegerExpression} are typically those that modify the value +of the source number itself, and thus performing them on an expression is meaningless. +Because through inheritance all operations are available on HugeInt, the descriptions below +do not specifically indicate whether each operator or method is defined for expressions, +or just for @code{HugeInt} instances. For the sake of brevity, they are listed as if they were methods of the @code{HugeInt} class. +Visual Studio provides Intellisense and immediate feedback to help sort out which operations are available +on expressions. + +Below is a brief summary of the supported multi-precision integer methods and operators. +To avoid repetition, implementation details are ommitted. Since MPIR native functions are called behind the scenes, +review @ref{Integer Functions} for further details about the native implementations. + +@deftypefn Constructor HugeInt () +@deftypefnx Constructor HugeInt ( int/long @var{n} ) +@deftypefnx Constructor HugeInt ( uint/ulong @var{n} ) +@deftypefnx Constructor HugeInt ( double @var{n} ) +Constructs a @code{HugeInt} object. Single-limb constructors vary by architecture, +32-bit builds take an @code{int} or @code{uint} argument, 64-bit builds take a @code{long} or @code{ulong}. +Any necessary conversion follows the corresponding C function, for +example @code{double} follows @code{mpz_set_d} (@pxref{Assigning Integers}). +@end deftypefn + +@deftypefn Constructor HugeInt ( string @var{s} ) +@deftypefnx Constructor HugeInt ( string @var{s}, int @var{base} ) +Constructs a @code{HugeInt} converted from a string using @code{mpz_set_str} +(@pxref{Assigning Integers}). If the string is not a valid integer, an exception is thrown. +@end deftypefn + +@deftypefn Constructor HugeInt ( IntegerExpression @var{e} ) +Evaluates the supplied expression and saves its result to the new instance. +Because @code{HugeInt} is derived from @code{IntegerExpression}, this constructor +can be used to make a copy of an existing variable, i.e. @code{HugeInt a = new HugeInt(b);} +without creating any permanent association between them. +@end deftypefn + +@deftypefn {Static Method} {static HugeInt} Allocate (mp_bitcnt_t @var{bits}) +@deftypefnx Method void Reallocate (mp_bitcnt_t @var{bits}) +Controls the capacity in bits of the allocated integer. +@end deftypefn + +@deftypefn Property int AllocatedSize +Returns the number of limbs currently allocated. +@end deftypefn + +@deftypefn Method ulong Size () +Returns the number of limbs currently used. +@end deftypefn + +@deftypefn Method long GetLimb (mp_size_t @var{index}) +Returns the specified limb. +@end deftypefn + +@deftypefn Method bool FitsUlong () //64-bit builds only +@deftypefnx Method bool FitsLong () //64-bit builds only +@deftypefnx Method bool FitsUint () +@deftypefnx Method bool FitsInt () +@deftypefnx Method bool FitsUshort () +@deftypefnx Method bool FitsShort () +@deftypefnx Method long ApproximateSizeInBase (int @var{base}) +Checks whether the number would fit in one of the built-in .Net types. +@end deftypefn + +@deftypefn Method string ToString () +@deftypefnx Method string ToString (int @var{base}) +@deftypefnx Method string ToString (int @var{base}, bool @var{lowercase}) +Returns the string representation of the number. The default @code{base} is 10, +and the parameterless overload is limited to 256 least significant digits by default, +producing a leading ellipsis (i.e. ...12345) when the number has more digits. This is done +to prevent huge numbers from unexpectedly consuming large amounts of memory in the debugger. +The maximum number of digits output is configurable via the @code{MpirSettings.ToStringDigits} property, +where zero means unlimited. The other overloads always output all digits. +@end deftypefn + +@deftypefn Method int ToInt () //32-bit builds +@deftypefnx Method uint ToUint () //32-bit builds +@deftypefnx Method long ToLong () //64-bit builds +@deftypefnx Method ulong ToUlong () //64-bit builds +@deftypefnx Method double ToDouble () +@deftypefnx Method double ToDouble (@code{out} int/long @var{exp}) +Converts the number to a primitive (built-in) .Net type, assuming it fits, +which can be determined by calling one of the @code{Fits...} methods. +@end deftypefn + +@deftypefn Property IntegerExpression Value +Getting this property is essentially a no-op, as it returns the object instance itself. +This never needs to be done explicitly, but is used implicitly in statements like @code{a.Value += 5;} + +Setting the @code{Value} property evaluates the assigned expression and saves the result to the object. +@end deftypefn + +@deftypefn Method void SetTo (int/long @var{value}) // 32/64-bit builds +@deftypefnx Method void SetTo (uint/ulong @var{value}) // 32/64-bit builds +@deftypefnx Method void SetTo (double @var{value}) +@deftypefnx Method void SetTo (string @var{value}) +@deftypefnx Method void SetTo (string @var{value}, int @var{base}) +@deftypefnx Method void SetTo (RationalExpression @var{value}) +@deftypefnx Method void SetTo (FloatExpression @var{value}) +Sets the value of existing variable from types other than @code{IntegerExpression}. +@end deftypefn + +Arithmetic operators (@code{+}, @code{-}, @code{*}, @code{/}, @code{%}) are overloaded to allow integers to participate +in expressions much like primitive integers can. Single-limb primitive types can be used. +These operators will also accept @code{RationalExpression} arguments, producing a @code{RationalExpression} result. +Some expression types expose additional methods, these are listed below. +Invoking these methods does not prevent the expression from participating in further expressions. + +Expressions resulting from division or computing a modulo allow setting an explicit rounding mode: +@example +c.Value = (a / b).Rounding(RoundingModes.Ceiling) + 4; +d.Value = (a % b).Rounding(RoundingModes.Floor) + 4; +@end example + +Division expressions optionally allow the remainder to be saved: +@example +c.Value = (a / b).SavingRemainderTo(e) + 4; +@end example + +When dividing by a limb, the remainder is a single limb and is saved to an unsigned limb variable. +However, passing this variable as an @code{out} argument would not work because +of the deferred evaluation. Instead, a delegate is passed which is called during evaluation: +@example +ulong/uint remainder; // 64/32-bit builds +d.Value = (a / 100).SettingRemainderTo(x => remainder = x) + 4; +@end example + +Symmetrically, the modulo expressions (@code{%}) allow the quotient to be saved: +@example +c.Value = (a % b).SavingQuotientTo(e).RoundingMode(RoundingModes.Ceiling) + 4; +ulong/uint quotient; // 64/32-bit builds +d.Value = (a % 100).SettingQuotientTo(x => quotient = x) + 4; +@end example + +@deftypefn Method uint/ulong Mod (uint/ulong @var{divisor}) +@deftypefnx Method uint/ulong Mod (uint/ulong @var{divisor}, RoundingModes @var{roundingMode}) +Computes the absolute value of the remainder from division of the source number by the specified @code{divisor}. +This operation differs from using the @code{%} operator by where the result is saved. +The @code{%} operator returns an expression, and a @code{HugeInt} variable is required to receive +the result when the expression is assigned to its @code{Value} property. +The @code{Mod} method, on the other hand, computes and returns the remainder immediately +since it's a primitive type (single limb), and no destination @code{HugeInt} variable is needed. +@end deftypefn + +Operator @code{^} serves dual purposes: when the right operand is a single limb, it raises the source number to a power, +if the right operand is an @code{IntegerExpression} it performs a bitwise XOR. + +Comparison operators (@code{==}, @code{!=}, @code{<}, @code{<=}, @code{>}, @code{>=}) accept @code{IntegerExpression}, +single-limb, or double arguments, but do not accept @code{RationalExpression} because that would require an awkward explicit cast +when comparing with null. + +@deftypefn Method int CompareTo (IntegerExpression @var{a}) +@deftypefnx Method bool Equals (IntegerExpression @var{a}) +Implement @code{IComparable} and @code{IEquatable} for strongly-typed comparisons. +@end deftypefn + +@deftypefn Method int CompareTo (object @var{a}) +@deftypefnx Method bool Equals (object @var{a}) +Implement @code{IComparable} and equality check for any object. These accept a @code{RationalExpression} as an argument, +allowing cross-type comparisons not possible with operators. +@end deftypefn + +@deftypefn Method int GetHashCode () +This @code{object} override computes the hash code. This is an O(n) operation where n is the number of limbs in use. +Changing a number's @code{Value} changes its hash code, so this should not be done on any object that has been added +to a hash table or dictionary. +@end deftypefn + +@deftypefn Method int CompareAbsTo (IntegerExpression @var{a}) +@deftypefnx Method int CompareAbsTo (uint/ulong @var{a}) +@deftypefnx Method int CompareAbsTo (double @var{a}) +Compares the absolute value of the number with the operand. +@end deftypefn + +@deftypefn Method int Sign () +Returns the number's sign. +@end deftypefn + +Bit shift operators (@code{<<}, @code{>>}) accept an unsigned limb operand. + +The right shift (@code{>>}) expression provides a method to compute the modulo, rather than the default quotient: +@example +var a = new HugeInt("0x1357"); +Debug.WriteLine((a >> 8).ToString(16)); //prints 13 +Debug.WriteLine((a >> 8).Remainder().ToString(16)); //prints 57 +@end example + +Bitwize operators (@code{&}, @code{|}, @code{^}, @code{~}) are defined for @code{IntegerExpression} operands only. +Note that operator @code{^} is also defined for a limb operand, and in that case computes a power. + +@deftypefn Method bool GetBit (uint/ulong @var{position}) +@deftypefnx Method void SetBit (uint/ulong @var{position}, bool @var{value}) +@deftypefnx Method void ComplementBit (uint/ulong @var{position}) +Allows access to individual bits of the number, using a "virtual" two's complement representation. +@end deftypefn + +@deftypefn Method uint/ulong PopCount () // 32/64-bit builds +Gets the number of set bits in the number. +@end deftypefn + +@deftypefn Method uint/ulong HammingDistance (IntegerExpression @var{target}) // 32/64-bit builds +Gets the hamming distance between this number and @code{target}. +@end deftypefn + +@deftypefn Method uint/ulong FindBit (bool @var{value}, uint/ulong @var{start}) // 32/64-bit builds +Scans the number for next set or cleared bit (depending on @code{value}). +@end deftypefn + +@deftypefn Method IntegerExpression Abs () +Returns an expression that computes the absolute value of the number. +@end deftypefn + +@deftypefn Method IntegerExpression DivideExactly (IntegerExpression @var{divisor}) +@deftypefnx Method IntegerExpression DivideExactly (uint/ulong @var{divisor}) // 32/64-bit builds +Returns an expression that performs a fast division where it is known that there is no remainder. +@end deftypefn + +@deftypefn Method IntegerExpression PowerMod (IntegerExpression @var{power}, IntegerExpression @var{modulo}) +@deftypefnx Method IntegerExpression PowerMod (uint/ulong @var{power}, IntegerExpression @var{modulo}) // 32/64-bit builds +Returns an expression that raises the source to the specified @code{power} modulo @code{modulo}. +@end deftypefn + +@deftypefn Method bool IsDivisibleBy (IntegerExpression @var{a}) +@deftypefnx Method bool IsDivisibleBy (uint/ulong @var{a}) +@deftypefnx Method bool IsDivisibleByPowerOf2 (uint/ulong @var{power}) +@deftypefnx Method bool IsCongruentTo (IntegerExpression @var{a}, IntegerExpression @var{modulo}) +@deftypefnx Method bool IsCongruentTo (uint/ulong @var{a}, uint/ulong @var{modulo}) +@deftypefnx Method bool IsCongruentToModPowerOf2 (IntegerExpression @var{a}, uint/ulong @var{power}) +@deftypefnx Method bool IsPerfectPower () +@deftypefnx Method bool IsPerfectSquare () +Performs various divisibility checks. These methods return a bool result, and therefore are executed immediately. +If they are called on an expression, the expression is evaluated to a temporary which is discarded immediately afterwards. +If you will need this result again, assign the expression to a @code{HugeInt} variable and call the method on it. +@end deftypefn + +@deftypefn Method long Write (Stream @var{stream}) +@deftypefnx Method long Write (TextWriter @var{writer}) +@deftypefnx Method long Write (TextWriter @var{writer}, int @var{base}) +@deftypefnx Method long Write (TextWriter @var{writer}, int @var{base}, bool @var{lowercase}) +@deftypefnx Method long Read (Stream @var{stream}) +@deftypefnx Method long Read (TextReader @var{reader}) +@deftypefnx Method long Read (TextReader @var{reader}, int @var{base}) +Writes and reads integers to/from streams using the raw binary format. +@end deftypefn + +@deftypefn Method void Import (T[] @var{data}, long @var{limbCount}, int @var{bytesPerLimb}, LimbOrder @var{limbOrder}, Endianness @var{endianness}, int @var{nails}) +@deftypefnx Method long Export (T[] @var{data}, int @var{bytesPerLimb}, LimbOrder @var{limbOrder}, Endianness @var{endianness}, int @var{nails}) +@deftypefnx Method T[] Export (int @var{bytesPerLimb}, LimbOrder @var{limbOrder}, Endianness @var{endianness}, int @var{nails}) +Imports/exports the absolute value of the number to/from arbitrary words of data. +@end deftypefn + +@deftypefn Method bool IsProbablePrime (MpirRandom @var{random}, int @var{probability}, ulong/uint @var{pretested}) +@deftypefnx Method bool IsLikelyPrime (MpirRandom @var{random}, ulong/uint @var{pretested}) +@deftypefnx {Static Method} {static int} Jacobi (HugeInteger @var{a}, HugeInteger @var{b}) +@deftypefnx {Static Method} {static int} Legendre (HugeInteger @var{a}, HugeInteger @var{b}) +@deftypefnx {Static Method} {static int} Kronecker (HugeInteger @var{a}, HugeInteger @var{b}) +@deftypefnx {Static Method} {static int} Kronecker (HugeInteger @var{a}, int/long @var{b}) +@deftypefnx {Static Method} {static int} Kronecker (HugeInteger @var{a}, uint/ulong @var{b}) +@deftypefnx {Static Method} {static int} Kronecker (int/long @var{a}, HugeInteger @var{b}) +@deftypefnx {Static Method} {static int} Kronecker (uint/ulong @var{a}, HugeInteger @var{b}) +@deftypefnx {Static Method} {static IntegerExpression} Power (uint/ulong @var{value}, uint/ulong @var{power}) +@deftypefnx {Static Method} {static IntegerExpression} Factorial (uint/ulong @var{value}) +@deftypefnx {Static Method} {static IntegerExpression} Factorial (uint/ulong @var{value}, uint/ulong @var{order}) +@deftypefnx {Static Method} {static IntegerExpression} Primorial (uint/ulong @var{value}) +@deftypefnx {Static Method} {static IntegerExpression} Binomial (uint/ulong @var{n}, uint/ulong @var{k}) +@deftypefnx {Static Method} {static IntegerExpression} Binomial (IntegerExpression @var{n}, uint/ulong @var{k}) +Performs various number-theoretic computations. +@end deftypefn + +@deftypefn {Static Method} {static IntegerSequenceExpression} Fibonacci (int/long @var{n}) +@deftypefnx {Static Method} {static IntegerSequenceExpression} Lucas (int/long @var{n}) +These two methods return a specialized expression that provides an additional method to optionally +save the previous number in the sequence, in addition to the number requested, for example: +@example +var b = new HugeInt(); +var c = new HugeInt(HugeInt.Fibonacci(300).SavingPreviousTo(b)); +@end example +@end deftypefn + +@deftypefn Method IntegerSquareRootExpression SquareRoot () +Returns an expression that evaluates to the square root of the number. The expression provides a method +to optionally save the remainder to a second variable: +@example +a.Value = b.SquareRoot().SavingRemainderTo(c); +@end example +@end deftypefn + +@deftypefn Method IntegerRootExpression Root (ulong/uint @var{power}) +Returns an expression that evaluates to the root of the specified @code{power} of the number. The expression provides two +optional methods. One allows to save the remainder to a second variable, and the other allows to set a boolean flag +indicating whether the root operation was exact. Note that computing the remainder is more costly than just getting an exact flag. +@example +bool exact = false; +a.Value = b.Root(3).SavingRemainderTo(r); +c.Value = d.Root(4).SettingExactTo(x => exact = x); +e.Value = f.Root(5).SavingRemainderTo(r).SettingExactTo(x => exact = x); +@end example +@end deftypefn + +@deftypefn Method IntegerExpression NextPrimeCandidate (MpirRandom @var{random}) +Returns an expression that looks for the next possible prime greater than the source number. +@end deftypefn + +@deftypefn Method uint/ulong Gcd (uint/ulong @var{a}) +Computes the greatest common divisor with the specified single-limb number. +@end deftypefn + +@deftypefn Method IntegerGcdExpression Gcd (IntegerExpression @var{a}) +Returns an expression that computes the greatest common divisor of the source number and @code{a}. +Provides a method to optionally calculate the related Diophantine equation multiplier(s): +@example +c.Value = a.Gcd(b).SavingDiophantineMultipliersTo(s, t); +@end example +If either @code{s} or @code{t} is null, that coefficient is not computed. +@end deftypefn + +@deftypefn Method IntegerExpression Lcm (IntegerExpression @var{a}) +@deftypefnx Method IntegerExpression Lcm (uint/ulong @var{a}) +Computes the least common multiple with @code{a}. +@end deftypefn + +@deftypefn Method IntegerExpression Invert (IntegerExpression @var{modulo}) +Returns an expression to compute the inverse of the source number modulo @code{modulo}. +@end deftypefn + +@deftypefn Method IntegerRemoveFactorsExpression RemoveFactors (IntegerExpression @var{factor}) +Returns an expression that evaluates to the result of removing all occurrences of the specified @code{factor} from the source number. +Provides a method to optionally save the number of factors that were removed: +@example +ulong/uint numberRemoved; // 64/32-bit builds +a.Value = b.RemoveFactors(c); +d.Value = e.RemoveFactors(f).SavingCountRemovedTo(x => numberRemoved = x); +@end example +@end deftypefn + +@node MPIR.Net Rationals, MPIR.Net Floats, MPIR.Net Integers, .Net Interface +@section MPIR.Net Rationals + + +@node MPIR.Net Floats, MPIR.Net Random Numbers, MPIR.Net Rationals, .Net Interface +@section MPIR.Net Floats + + +@node MPIR.Net Random Numbers, MPIR.Net Limitations, MPIR.Net Floats, .Net Interface +@section MPIR.Net Random Numbers + + + +@node MPIR.Net Limitations, , MPIR.Net Random Numbers, .Net Interface +@section MPIR.Net Limitations + + +@node Custom Allocation, Language Bindings, .Net Interface, Top @comment node-name, next, previous, up @chapter Custom Allocation @cindex Custom allocation @@ -10494,3 +11110,4 @@ volume 43, number 8, August 1994, pp.@: 899-908. @c fill-column: 78 @c compile-command: "make mpir.info" @c End: +