Updated XML documents to match MPIR 2.7.2 documentation, and added mixed comparisons between rationals and integers based on the new mpq_cmp_z function.
This commit is contained in:
parent
b006a3b4d9
commit
d895d98428
@ -41,6 +41,33 @@ namespace MPIR.Tests.HugeRationalTests
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void RationalCompareToHugeInt()
|
||||
{
|
||||
using (var a = new HugeRational("-222509832503450298345029835740293845721/115756986668303657898962467957"))
|
||||
using (var b = new HugeInt("115756986668303657898962467957"))
|
||||
using (var c = new HugeRational("115756986668303657898962467957/1"))
|
||||
using (var d = new HugeInt(1922215141))
|
||||
{
|
||||
Assert.AreEqual(-1, System.Math.Sign(a.CompareTo(d)));
|
||||
Assert.AreEqual(1, System.Math.Sign((-a).CompareTo(d)));
|
||||
Assert.AreEqual(-1, System.Math.Sign((-a).CompareTo(d + 1)));
|
||||
Assert.AreEqual(1, System.Math.Sign(d.CompareTo(a)));
|
||||
Assert.AreEqual(-1, System.Math.Sign(d.CompareTo(-a)));
|
||||
Assert.AreEqual(1, System.Math.Sign((d + 1).CompareTo(-a)));
|
||||
|
||||
Assert.AreEqual(0, System.Math.Sign(b.CompareTo(c)));
|
||||
Assert.AreEqual(0, System.Math.Sign(c.CompareTo(b)));
|
||||
Assert.AreEqual(0, System.Math.Sign((-b).CompareTo(-c)));
|
||||
Assert.AreEqual(0, System.Math.Sign((-c).CompareTo(-b)));
|
||||
|
||||
Assert.AreEqual(1, System.Math.Sign(b.CompareTo(c - 1)));
|
||||
Assert.AreEqual(1, System.Math.Sign(c.CompareTo(b - 1)));
|
||||
Assert.AreEqual(-1, System.Math.Sign((-b).CompareTo(1 - c)));
|
||||
Assert.AreEqual(-1, System.Math.Sign((-c).CompareTo(1 - b)));
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void RationalCompareToObject()
|
||||
{
|
||||
@ -437,6 +464,28 @@ namespace MPIR.Tests.HugeRationalTests
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void RationalEqualsHugeInt()
|
||||
{
|
||||
using (var a = new HugeRational("-222509832503450298345029835740293845721/115756986668303657898962467957"))
|
||||
using (var b = new HugeInt(1922215142))
|
||||
using (var c = new HugeRational("115756986668303657898962467957/1"))
|
||||
using (var d = new HugeInt("-115756986668303657898962467957"))
|
||||
{
|
||||
Assert.IsFalse(a.Equals(b));
|
||||
Assert.IsFalse(b.Equals(a));
|
||||
Assert.IsFalse(a.Equals(-b));
|
||||
Assert.IsFalse(b.Equals(-a));
|
||||
Assert.IsFalse(c.Equals(d));
|
||||
Assert.IsTrue(c.Equals(-d));
|
||||
Assert.IsTrue((-c).Equals(d));
|
||||
Assert.IsTrue(d.Equals(-c));
|
||||
Assert.IsTrue((-d).Equals(c));
|
||||
Assert.IsTrue(Equals(c, -d));
|
||||
Assert.IsTrue(Equals(-c, d));
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void RationalEqualsExpression()
|
||||
{
|
||||
|
@ -172,40 +172,7 @@ namespace MPIR
|
||||
|
||||
#pragma region Interface implementations
|
||||
|
||||
int MPEXPR_NAME::CompareTo(Object^ a, bool& valid)
|
||||
{
|
||||
valid = true;
|
||||
|
||||
if (IS_NULL(a))
|
||||
return 1;
|
||||
|
||||
MPEXPR_NAME^ expr = dynamic_cast<MPEXPR_NAME^>(a);
|
||||
if(!IS_NULL(expr))
|
||||
return CompareTo(expr);
|
||||
|
||||
EvaluationContext context;
|
||||
|
||||
if(a->GetType() == mpir_ui::typeid)
|
||||
{
|
||||
ASSIGN_TO(context);
|
||||
return MP(cmp_ui)(CTXT(0), (mpir_ui)a);
|
||||
}
|
||||
|
||||
if(a->GetType() == mpir_si::typeid)
|
||||
{
|
||||
ASSIGN_TO(context);
|
||||
return MP(cmp_si)(CTXT(0), (mpir_si)a);
|
||||
}
|
||||
|
||||
if(a->GetType() == double::typeid)
|
||||
{
|
||||
ASSIGN_TO(context);
|
||||
return MP(cmp_d)(CTXT(0), (double)a);
|
||||
}
|
||||
|
||||
valid = false;
|
||||
return 0;
|
||||
}
|
||||
//CompareTo has to be defined in HugeRational.cpp because it depends on HugeRational.h
|
||||
|
||||
int MPEXPR_NAME::CompareTo(Object^ a)
|
||||
{
|
||||
|
@ -446,8 +446,11 @@ namespace MPIR
|
||||
|
||||
/// <summary>Compares two numbers.
|
||||
/// <para>If any argument is an expression, it is evaluated into a temporary variable before the comparison is performed.
|
||||
/// </para></summary>
|
||||
/// <param name="a">Value to compare the source with</param>
|
||||
/// </para>Both this method and Equals() allow the argument to be a RationalExpression, however we do not define mixed equality operators,
|
||||
/// because otherwise testing for a null/non-null expression would require an awkward explicit cast on the null.
|
||||
/// <para>Although this only applies to equality operators, while comparison operators could have possibly worked, we're leaving out all mixed operators for now.
|
||||
/// </para>Since comparison via CompareTo() or Equals() is possible between ints and rationals, operators would just be another way to do the same thing.</summary>
|
||||
/// <param name="a">Value to compare the source with. This can be an integer or rational multi-precision number or expression, or a supported primitive type (long, ulong, or double).</param>
|
||||
/// <returns>A positive number if the source is greater than <paramref name="a"/>, negative if less, and zero if they are equal.</returns>
|
||||
virtual int CompareTo(Object^ a) sealed;
|
||||
|
||||
@ -467,8 +470,11 @@ namespace MPIR
|
||||
|
||||
/// <summary>Compares two numbers.
|
||||
/// <para>If any argument is an expression, it is evaluated into a temporary variable before the comparison is performed.
|
||||
/// </para></summary>
|
||||
/// <param name="a">Value to compare the source with. This can be a multi-precision number, an expression, or a supported primitive type (long, ulong, or double).</param>
|
||||
/// </para>Both this method and CompareTo() allow the argument to be a RationalExpression, however we do not define mixed equality operators,
|
||||
/// because otherwise testing for a null/non-null expression would require an awkward explicit cast on the null.
|
||||
/// <para>Although this only applies to equality operators, while comparison operators could have possibly worked, we're leaving out all mixed operators for now.
|
||||
/// </para>Since comparison via CompareTo() or Equals() is possible between ints and rationals, operators would just be another way to do the same thing.</summary>
|
||||
/// <param name="a">Value to compare the source with. This can be an integer or rational multi-precision number or expression, or a supported primitive type (long, ulong, or double).</param>
|
||||
/// <returns>true if the values of the source and <paramref name="a"/> are equal, false otherwise.</returns>
|
||||
virtual bool Equals(Object^ a) override sealed;
|
||||
|
||||
@ -939,7 +945,7 @@ namespace MPIR
|
||||
MPEXPR_NAME^ NextPrimeCandidate(MpirRandom^ random);
|
||||
|
||||
/// <summary>Computes the greatest common divisor of this number and <paramref name="a"/>.
|
||||
/// <para>The result is always positive even if one or both inputs are negative.
|
||||
/// <para>The result is always positive even if one or both inputs are negative (or zero if both inputs are zero).
|
||||
/// </para>As with all expressions, the result is not computed until the expression is assigned to the Value property or consumed by a method.
|
||||
/// </summary>
|
||||
/// <param name="a">Source value to compute the GCD with</param>
|
||||
@ -1245,9 +1251,14 @@ namespace MPIR
|
||||
|
||||
public:
|
||||
/// <summary>
|
||||
/// Optionally computes and saves the coefficients <paramref name="s"/> and <paramref name="t"/> such that x*s + y*t = gcd(x, y).
|
||||
/// Optionally computes and saves the coefficients <paramref name="s"/> and <paramref name="t"/> such that a<paramref name="s"/> + b<paramref name="t"/> = g = gcd(a, b).
|
||||
/// <para>If only one of the coefficients is needed, use null for the other.
|
||||
/// </para></summary>
|
||||
/// </para>The values <paramref name="s"/> and <paramref name="t"/> are chosen such that normally, |<paramref name="s"/>| < |b|/(2g) and |<paramref name="t"/>| < |a|/(2g),
|
||||
/// and these relations define <paramref name="s"/> and <paramref name="t"/> uniquely.
|
||||
/// <para>There are a few exceptional cases:
|
||||
/// </para>If |a| = |b|, then <paramref name="s"/> = 0 and <paramref name="t"/> = sgn(b).
|
||||
/// <para>Otherwise, <paramref name="s"/> = sgn(a) if b = 0 or |b| = 2g, and <paramref name="t"/> = sgn(b) if a = 0 or |a| = 2g.
|
||||
/// </para>In all cases, <paramref name="s"/> = 0 if and only if g = |b|, i.e., if b divides a or a = b = 0.</summary>
|
||||
/// <param name="s">destination for the first coefficient. Can be null if not needed.</param>
|
||||
/// <param name="t">destination for the second coefficient. Can be null if not needed.</param>
|
||||
/// <returns>An updated expression, with its internal state updated to save the coefficients.</returns>
|
||||
|
@ -165,6 +165,14 @@ namespace MPIR
|
||||
|
||||
EvaluationContext context;
|
||||
|
||||
IntegerExpression^ expr2 = dynamic_cast<IntegerExpression^>(a);
|
||||
if (!IS_NULL(expr2))
|
||||
{
|
||||
ASSIGN_TO(context);
|
||||
expr2->AssignToInteger(context);
|
||||
return MP(cmp_z)(CTXT(0), CTXTI(1));
|
||||
}
|
||||
|
||||
if(a->GetType() == mpir_ui::typeid)
|
||||
{
|
||||
ASSIGN_TO(context);
|
||||
@ -231,6 +239,14 @@ namespace MPIR
|
||||
|
||||
EvaluationContext context;
|
||||
|
||||
IntegerExpression^ expr2 = dynamic_cast<IntegerExpression^>(a);
|
||||
if (!IS_NULL(expr2))
|
||||
{
|
||||
ASSIGN_TO(context);
|
||||
expr2->AssignToRational(context);
|
||||
return MP(equal)(CTXT(0), CTXT(1)) != 0;
|
||||
}
|
||||
|
||||
if(a->GetType() == mpir_ui::typeid)
|
||||
{
|
||||
ASSIGN_TO(context);
|
||||
@ -437,5 +453,48 @@ namespace MPIR
|
||||
mpf_set_q(_value, CTXT(0));
|
||||
}
|
||||
|
||||
int IntegerExpression::CompareTo(Object^ a, bool& valid)
|
||||
{
|
||||
valid = true;
|
||||
|
||||
if (IS_NULL(a))
|
||||
return 1;
|
||||
|
||||
IntegerExpression^ expr = dynamic_cast<IntegerExpression^>(a);
|
||||
if (!IS_NULL(expr))
|
||||
return CompareTo(expr);
|
||||
|
||||
EvaluationContext context;
|
||||
|
||||
MPEXPR_NAME^ expr2 = dynamic_cast<MPEXPR_NAME^>(a);
|
||||
if (!IS_NULL(expr2))
|
||||
{
|
||||
expr2->AssignToRational(context);
|
||||
AssignToInteger(context);
|
||||
return -MP(cmp_z)(CTXT(0), CTXTI(1));
|
||||
}
|
||||
|
||||
if (a->GetType() == mpir_ui::typeid)
|
||||
{
|
||||
AssignToInteger(context);
|
||||
return mpz_cmp_ui(CTXTI(0), (mpir_ui)a);
|
||||
}
|
||||
|
||||
if (a->GetType() == mpir_si::typeid)
|
||||
{
|
||||
AssignToInteger(context);
|
||||
return mpz_cmp_si(CTXTI(0), (mpir_si)a);
|
||||
}
|
||||
|
||||
if (a->GetType() == double::typeid)
|
||||
{
|
||||
AssignToInteger(context);
|
||||
return mpz_cmp_d(CTXTI(0), (double)a);
|
||||
}
|
||||
|
||||
valid = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
};
|
@ -376,8 +376,11 @@ namespace MPIR
|
||||
|
||||
/// <summary>Compares two numbers.
|
||||
/// <para>If any argument is an expression, it is evaluated into a temporary variable before the comparison is performed.
|
||||
/// </para></summary>
|
||||
/// <param name="a">Value to compare the source with</param>
|
||||
/// </para>Both this method and Equals() allow the argument to be an IntegerExpression, however we do not define mixed equality operators,
|
||||
/// because otherwise testing for a null/non-null expression would require an awkward explicit cast on the null.
|
||||
/// <para>Although this only applies to equality operators, while comparison operators could have possibly worked, we're leaving out all mixed operators for now.
|
||||
/// </para>Since comparison via CompareTo() or Equals() is possible between ints and rationals, operators would just be another way to do the same thing.</summary>
|
||||
/// <param name="a">Value to compare the source with. This can be an integer or rational multi-precision number or expression, or a supported primitive type (long, ulong, or double).</param>
|
||||
/// <returns>A positive number if the source is greater than <paramref name="a"/>, negative if less, and zero if they are equal.</returns>
|
||||
virtual int CompareTo(Object^ a) sealed;
|
||||
|
||||
@ -413,8 +416,11 @@ namespace MPIR
|
||||
|
||||
/// <summary>Compares two numbers.
|
||||
/// <para>If any argument is an expression, it is evaluated into a temporary variable before the comparison is performed.
|
||||
/// </para></summary>
|
||||
/// <param name="a">Value to compare the source with. This can be a multi-precision number, an expression, or a supported primitive type (long, ulong, or double).</param>
|
||||
/// </para>Both this method and CompareTo() allow the argument to be an IntegerExpression, however we do not define mixed equality operators,
|
||||
/// because otherwise testing for a null/non-null expression would require an awkward explicit cast on the null.
|
||||
/// <para>Although this only applies to equality operators, while comparison operators could have possibly worked, we're leaving out all mixed operators for now.
|
||||
/// </para>Since comparison via CompareTo() or Equals() is possible between ints and rationals, operators would just be another way to do the same thing.</summary>
|
||||
/// <param name="a">Value to compare the source with. This can be an integer or rational multi-precision number or expression, or a supported primitive type (long, ulong, or double).</param>
|
||||
/// <returns>true if the values of the source and <paramref name="a"/> are equal, false otherwise.</returns>
|
||||
virtual bool Equals(Object^ a) override sealed;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user