Next: MPIR.Net Floats, Previous: MPIR.Net Integers, Up: .Net Interface [Index]
MPIR multi-precision rational numbers are represented by the HugeRational
class,
along with its corresponding expression class RationalExpression
,
which is returned from all operators and methods whose
value semantics are to compute another number from the source instance and any arguments.
Operations defined on HugeRational
but not on RationalExpression
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 HugeRational
, the descriptions below
do not specifically indicate whether each operator or method is defined for expressions,
or just for HugeRational
instances. For the sake of brevity, they are listed as if they were methods of the HugeRational
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 rational methods and operators. To avoid repetition, implementation details are ommitted. Since MPIR native functions are called behind the scenes, review Rational Number Functions for further details about the native implementations.
Constructs a HugeRational
object. Single-limb constructors vary by architecture,
32-bit builds take int
or uint
arguments, 64-bit builds take long
or ulong
.
Any necessary conversion follows the corresponding C function, for
example double
follows mpq_set_d
(see Initialization and Assignment Functions).
Constructs a HugeRational
converted from a string using mpq_set_str
(see Initialization and Assignment Functions). If the string is not a valid integer or rational, an exception is thrown.
When constructing a rational number from a numerator and denominator, including
the string constructors where both numerator and denominator are specified, the fraction
should be in canonical form, or if not then Canonicalize()
should be called.
Evaluates the supplied expression and saves its result to the new instance.
Because multi-precision classes are derived from their corresponding expression classes,
these constructors can be used to make a copy of an existing variable, i.e. HugeRational a = new HugeRational(b);
without creating any permanent association between them.
Controls the capacity in bits of the allocated integer. HugeRational does not have a Reallocate
method,
but its numerator and demonimator are derived from HugeInt and can thus be reallocated separately.
Puts a HugeRational
into canonical form, as per Rational Number Functions. All arithmetic operators require their operands in canonical
form, and will return results in canonical form.
These read-only properties expose the numerator and denominator for direct manipulation.
They return specialized instances of the HugeInt
class
that do not own their limb data. They override the Dispose()
method with a no-op, so they can be safely passed
around as normal integers, even to code that tries to dispose of them.
Once a numerator or denominator is obtained, it remains valid for the life of the HugeRational
instance.
It references live data, so for example, if the Value
of the rational is modified,
it will be visible through a previously obtained numerator/denominator instance.
Conversely, setting the Value
of a numerator or denominator modifies the Value
of its owning rational,
and if this cannot be known to keep the rational in canonical form, Canonicalize()
must be called
before performing any further MPIR operations on the rational.
Multiple copies can be safely obtained, and reference the same internal structures.
Once the HugeRational
is disposed, any numerator and denominator instances obtained from it
are no longer valid.
Returns the number of digits the absolute value of number would take if written in the specified base. The result can be at most 2 characters too long, and allows for a numerator, a division sign, and a denominator, but excludes the leading minus sign.
Returns the string representation of the number. The default base
is 10,
and the parameterless overload is limited to 256 least significant digits by default,
each for a numerator and a denominator, producing a leading ellipsis (i.e. ...12345)
when either component 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 MpirSettings.ToStringDigits
property,
where zero means unlimited. The other overloads always output all digits.
Converts the number to a double, possibly truncated.
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 a.Value += 5;
Setting the Value
property evaluates the assigned expression and saves the result to the object.
Sets the value of existing variable from types other than RationalExpression
.
When setting both the numerator and denominator, canonicalization must be
managed explicitly.
Swaps the values of the two objects. This is an O(1) operation. Any existing numerators and denominators remain associated with the object on which they were obtained, and reflect its new value.
Arithmetic operators (+
, -
, *
, /
) are overloaded to allow rationals to participate
in expressions much like primitive integers can. Single-limb primitive types can be used.
These operators will also accept IntegerExpression
arguments,
and will automatically promote them. In expressions, promotion of an IntegerExpression
to a RationalExpression
is an O(1) operation. Of course, when constructing a rational
from an integer, a copy is made so this becomes O(N).
Due to the rationals’ nature, division is always exact (there is no rounding)
and the modulo operator (%
) is not defined.
Also not defined are the bit shift operators (<<
, >>
),
and the bitwise operators (&
, |
, ^
, ~
).
Operator ^
raises the source number to the specified power.
Comparison operators (==
, !=
, <
, <=
, >
, >=
) accept RationalExpression
,
single-limb, or double arguments, but do not accept integer or float expressions because that would require an awkward explicit cast
when comparing with null. Use the CompareTo(object)
method for cross-comparisons.
Implement IComparable<RationalExpression>
and IEquatable<RationalExpression>
for strongly-typed comparisons.
Implement IComparable
and equality check for any object.
For rationals, these methods support any expression type (integer, rational, or float).
Single-limb comparisons for rationals take two arguments.
This object
override computes the hash code. This is an O(N) operation where N is the number of limbs in use
in the numerator and denominator combined.
Changing a number’s Value
changes its hash code, so this should not be done on any object that has been added
to a hash table or dictionary.
Returns the number’s sign.
Returns an expression that computes the absolute value of the number.
Returns an expression that computes the inverse of the number.
Writes and reads rationals to/from streams using the raw binary format.
Writes and reads rationals as text.
There are no Import
/Export
methods, but they can of course be invoked
on the numerator and/or denominator.
RationalExpression
does not have any specialized subclasses, as there are no
operations on the rational type that require additional inputs beyond the left and right
operator operands.
Next: MPIR.Net Floats, Previous: MPIR.Net Integers, Up: .Net Interface [Index]