MPIR.Net CompareTo updated to use mpf_cmp_z for mixed float/int comparisons

This commit is contained in:
Alex Dyachenko 2019-06-24 17:48:13 -04:00
parent 9c5740fe53
commit 36cdf4ad96
6 changed files with 61 additions and 4 deletions

View File

@ -7390,8 +7390,9 @@ Operator @code{^} serves dual purposes: when the right operand is a single limb,
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
single-limb, or double arguments, but do not accept @code{RationalExpression} or @code{FloatExpression} because that would require an awkward explicit cast
when comparing with null.
Use the @code{CompareTo(object)} method for cross-comparisons, which does accept both @code{RationalExpression} and @code{FloatExpression}.
@deftypefn Method int CompareTo (IntegerExpression @var{a})
@deftypefnx Method bool Equals (IntegerExpression @var{a})
@ -7725,8 +7726,9 @@ and the bitwise operators (@code{&}, @code{|}, @code{^}, @code{~}).
Operator @code{^} raises the source number to the specified power.
Comparison operators (@code{==}, @code{!=}, @code{<}, @code{<=}, @code{>}, @code{>=}) accept @code{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 @code{CompareTo(object)} method for cross-comparisons.
single-limb, or double arguments, but do not accept @code{IntegerExpression} or @code{FloatExpression} because that would require an awkward explicit cast
when comparing with null.
Use the @code{CompareTo(object)} method for cross-comparisons with integers. Direct comparisons between rationals and floats are not available in MPIR.
@deftypefn Method int CompareTo (RationalExpression @var{a})
@deftypefnx Method bool Equals (RationalExpression @var{a})
@ -7940,8 +7942,9 @@ The modulo operator (@code{%}) and the bitwise operators (@code{&}, @code{|}, @c
Operator @code{^} raises the source number to the specified power.
Comparison operators (@code{==}, @code{!=}, @code{<}, @code{<=}, @code{>}, @code{>=}) accept @code{FloatExpression},
single-limb, or double arguments, but do not accept integer or rational expressions
single-limb, or double arguments, but do not accept @code{RationalExpression} or @code{IntegerExpression}
because that would require an awkward explicit cast when comparing with null.
Use the @code{CompareTo(object)} method for cross-comparisons with integers. Direct comparisons between rationals and floats are not available in MPIR.
@deftypefn Method int CompareTo (FloatExpression @var{a})
@deftypefnx Method bool Equals (FloatExpression @var{a})

View File

@ -66,6 +66,24 @@ namespace MPIR.Tests.HugeFloatTests
}
}
[TestMethod]
public void FloatCompareToHugeIntExpression()
{
using (var a = new HugeFloat("-222509832503450298345039835740293845721345345354"))
using (var b = new HugeInt("222509832503450298345039835740293845721345345353"))
{
Assert.AreEqual(-1, Math.Sign(a.CompareTo(b)));
Assert.AreEqual(-1, Math.Sign(a.CompareTo(-b)));
Assert.AreEqual(0, Math.Sign(a.CompareTo(-b - 1)));
Assert.AreEqual(1, Math.Sign(a.CompareTo(-b - 2)));
Assert.AreEqual(-1, Math.Sign((a + 1).CompareTo(b)));
Assert.AreEqual(0, Math.Sign((a + 1).CompareTo(-b)));
Assert.AreEqual(-1, Math.Sign((a + 1).CompareTo(1 - b)));
Assert.AreEqual(1, Math.Sign((a + 1).CompareTo(-b - 1)));
}
}
[TestMethod]
[ExpectedException(typeof(ArgumentException))]
public void FloatCompareToNonExpression()

View File

@ -66,6 +66,24 @@ namespace MPIR.Tests.HugeIntTests
}
}
[TestMethod]
public void IntCompareToHugeFloatExpression()
{
using (var a = new HugeInt("-222509832503450298345039835740293845721345345354"))
using (var b = new HugeFloat("222509832503450298345039835740293845721345345353"))
{
Assert.AreEqual(-1, System.Math.Sign(a.CompareTo(b)));
Assert.AreEqual(-1, System.Math.Sign(a.CompareTo(-b)));
Assert.AreEqual(0, System.Math.Sign(a.CompareTo(-b - 1)));
Assert.AreEqual(1, System.Math.Sign(a.CompareTo(-b - 2)));
Assert.AreEqual(-1, System.Math.Sign((a + 1).CompareTo(b)));
Assert.AreEqual(0, System.Math.Sign((a + 1).CompareTo(-b)));
Assert.AreEqual(-1, System.Math.Sign((a + 1).CompareTo(1 - b)));
Assert.AreEqual(1, System.Math.Sign((a + 1).CompareTo(-b - 1)));
}
}
[TestMethod]
[ExpectedException(typeof(ArgumentException))]
public void IntCompareToNonExpression()

View File

@ -210,6 +210,13 @@ namespace MPIR
auto f = dynamic_cast<MPTYPE^>(this);
auto precision = IS_NULL(f) ? MPTYPE::DefaultPrecision : f->Precision;
WHEN_IS(2, a, IntegerExpression)
{
IN_SPECIFIC_CONTEXT(precision, this);
x2->AssignToInteger(context);
return MP(cmp_z)(CTXT(0), CTXTI(1));
}
if(a->GetType() == mpir_ui::typeid)
{
IN_SPECIFIC_CONTEXT(precision, this);

View File

@ -468,6 +468,16 @@ namespace MPIR
return -MP(cmp_z)(CTXT(0), CTXTI(1));
}
WHEN_IS(3, a, FloatExpression)
{
auto const f = dynamic_cast<HugeFloat^>(a);
context.FloatPrecision = IS_NULL(f) ? HugeFloat::DefaultPrecision : f->Precision;
x3->AssignToFloat(context);
AssignToInteger(context);
return -mpf_cmp_z(CTXTF(0), CTXTI(1));
}
if (a->GetType() == mpir_ui::typeid)
{
AssignToInteger(context);

View File

@ -49,6 +49,7 @@ using namespace System::Runtime::InteropServices;
#define MPEXPR(x) LIT(MPTYPE_NAME)##x##Expression
#define CTXT(x) context.RationalArgs[x]
#define CTXTI(x) context.IntArgs[x]
#define CTXTF(x) context.FloatArgs[x]
#define ASSIGN_TO CONCAT(AssignTo, LIT(MPTYPE_NAME))
#define SET_CONTEXT_PRECISION
#include "ExpressionMacros.h"