Added a .Net Interface chapter to the manual. Integer section completed.

This commit is contained in:
Alex Dyachenko 2016-06-06 20:24:21 -04:00
parent 05c71611a9
commit 06a8e90815

View File

@ -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<IntegerExpression>} and @code{IEquatable<IntegerExpression>} 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> (T[] @var{data}, long @var{limbCount}, int @var{bytesPerLimb}, LimbOrder @var{limbOrder}, Endianness @var{endianness}, int @var{nails})
@deftypefnx Method long Export<T> (T[] @var{data}, int @var{bytesPerLimb}, LimbOrder @var{limbOrder}, Endianness @var{endianness}, int @var{nails})
@deftypefnx Method T[] Export<T> (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: