Redefined MPIR.Net addition and subtraction assignment to use addmul/submul when applicable
This commit is contained in:
parent
65aba6b72f
commit
bd0da54f7e
@ -263,6 +263,19 @@ namespace MPIR.Tests.HugeIntTests
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void IntAddProductHugeInt2()
|
||||
{
|
||||
using (var a = new HugeInt("98750293847520938457029384572093480498357"))
|
||||
using (var c = new HugeInt("23094582093845093574093845093485039450934"))
|
||||
using (var b = new HugeInt("-394580293847502987609283945873594873409587"))
|
||||
{
|
||||
var expr = c * b + a;
|
||||
a.Value = expr;
|
||||
Assert.AreEqual("-9112666988874677841199955832262586145147830205230375090322356322089362221491205901", a.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void IntAddProductLimb()
|
||||
{
|
||||
@ -369,6 +382,19 @@ namespace MPIR.Tests.HugeIntTests
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void IntAddProductSignedLimbTo4()
|
||||
{
|
||||
using (var a = new HugeInt("98750293847520938457029384572093480498357"))
|
||||
using (var c = new HugeInt("23094582093845093574093845093485039450934"))
|
||||
{
|
||||
var b = Platform.Si(-498734523097853458, -2017853458);
|
||||
var expr = b * c + a;
|
||||
a.Value = expr;
|
||||
Assert.AreEqual(Platform.Select("-11518065386718058599763388064972875060082210203928832731415", "-46601482240379908737297906081375735555240112731415"), a.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Subtract Product
|
||||
@ -386,6 +412,19 @@ namespace MPIR.Tests.HugeIntTests
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void IntSubtractProductHugeIntFrom()
|
||||
{
|
||||
using (var a = new HugeInt("98750293847520938457029384572093480498359"))
|
||||
using (var c = new HugeInt("23094582093845093574093845093485039450934"))
|
||||
using (var b = new HugeInt("394580293847502987609283945873594873409587"))
|
||||
{
|
||||
var expr = c * b - a;
|
||||
a.Value = expr;
|
||||
Assert.AreEqual("9112666988874677841199955832262586145147830205230375090322356322089362221491205899", a.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void IntSubtractProductLimb()
|
||||
{
|
||||
@ -399,6 +438,19 @@ namespace MPIR.Tests.HugeIntTests
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void IntSubtractProductLimbFrom()
|
||||
{
|
||||
using (var a = new HugeInt("98750293847520938457029384572093480498359"))
|
||||
using (var c = new HugeInt("23094582093845093574093845093485039450934"))
|
||||
{
|
||||
var b = Platform.Ui(498734523097853458, 3997853458);
|
||||
var expr = c * b - a;
|
||||
a.Value = expr;
|
||||
Assert.AreEqual(Platform.Select("11518065386718058599763388064972875060082210203928832731413", "92328754786193194014003719366476113668089432731413"), a.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void IntSubtractProductSignedLimb()
|
||||
{
|
||||
@ -412,6 +464,19 @@ namespace MPIR.Tests.HugeIntTests
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void IntSubtractProductSignedLimbFrom()
|
||||
{
|
||||
using (var a = new HugeInt("98750293847520938457029384572093480498359"))
|
||||
using (var c = new HugeInt("-23094582093845093574093845093485039450934"))
|
||||
{
|
||||
var b = Platform.Si(-498734523097853458, -2017853458);
|
||||
var expr = b * c - a;
|
||||
a.Value = expr;
|
||||
Assert.AreEqual(Platform.Select("11518065386718058599763388064972875060082210203928832731413", "46601482240379908737297906081375735555240112731413"), a.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void IntSubtractProductSignedLimb2()
|
||||
{
|
||||
@ -437,6 +502,30 @@ namespace MPIR.Tests.HugeIntTests
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void IntSubtractProductSignedLimbFrom3()
|
||||
{
|
||||
using (var a = new HugeInt("98750293847520938457029384572093480498359"))
|
||||
using (var c = new HugeInt("-23094582093845093574093845093485039450934"))
|
||||
{
|
||||
var b = Platform.Si(498734523097853458, 2017853458);
|
||||
a.Value = c * b - a;
|
||||
Assert.AreEqual(Platform.Select("-11518065386718058797263975760014751974140979348115793728131", "-46601482437880496432339782995434504699427073728131"), a.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void IntSubtractProductSignedLimb4()
|
||||
{
|
||||
using (var a = new HugeInt("98750293847520938457029384572093480498357"))
|
||||
using (var c = new HugeInt("23094582093845093574093845093485039450934"))
|
||||
{
|
||||
var b = Platform.Si(498734523097853458, 2017853458);
|
||||
a.Value = a - c * b;
|
||||
Assert.AreEqual(Platform.Select("-11518065386718058599763388064972875060082210203928832731415", "-46601482240379908737297906081375735555240112731415"), a.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Shift Left
|
||||
|
@ -59,7 +59,7 @@ along with the MPIR Library. If not, see http://www.gnu.org/licenses/.
|
||||
private ref class MPEXPR(name) : base \
|
||||
{ \
|
||||
internal: \
|
||||
type Operand; \
|
||||
initonly type Operand; \
|
||||
virtual void AssignTo(MP(ptr) destination) override; \
|
||||
MPEXPR(name)(type operand) \
|
||||
{ \
|
||||
@ -72,8 +72,8 @@ private ref class MPEXPR(name) : base \
|
||||
private ref class MPEXPR(name) : base \
|
||||
{ \
|
||||
internal: \
|
||||
leftType Left; \
|
||||
rightType Right; \
|
||||
initonly leftType Left; \
|
||||
initonly rightType Right; \
|
||||
virtual void AssignTo(MP(ptr) destination) override; \
|
||||
MPEXPR(name)(leftType left, rightType right) \
|
||||
{ \
|
||||
@ -87,9 +87,9 @@ private ref class MPEXPR(name) : base \
|
||||
private ref class MPEXPR(name) : base \
|
||||
{ \
|
||||
internal: \
|
||||
leftType Left; \
|
||||
middleType Middle; \
|
||||
rightType Right; \
|
||||
initonly leftType Left; \
|
||||
initonly middleType Middle; \
|
||||
initonly rightType Right; \
|
||||
virtual void AssignTo(MP(ptr) destination) override; \
|
||||
MPEXPR(name)(leftType left, middleType middle, rightType right) \
|
||||
{ \
|
||||
|
@ -435,11 +435,9 @@ namespace MPIR
|
||||
DEFINE_UNARY_ASSIGNMENT_REF(Negate, Int, MP(neg))
|
||||
DEFINE_UNARY_ASSIGNMENT_REF(Abs, Int, MP(abs))
|
||||
|
||||
DEFINE_BINARY_ASSIGNMENT_REF_REF(Add, Int, MP(add))
|
||||
DEFINE_BINARY_ASSIGNMENT_REF_VAL(Add, Int, Ui, MP(add_ui))
|
||||
DEFINE_BINARY_ASSIGNMENT_REF_SI (Add, Int, Si, MP(add_ui), MP(sub_ui))
|
||||
|
||||
DEFINE_BINARY_ASSIGNMENT_REF_REF(Subtract, Int, MP(sub))
|
||||
DEFINE_BINARY_ASSIGNMENT_REF_VAL(Subtract, Int, Ui, MP(sub_ui))
|
||||
DEFINE_BINARY_ASSIGNMENT_VAL_REF(Subtract, Ui, Int, MP(ui_sub))
|
||||
DEFINE_BINARY_ASSIGNMENT_REF_SI (Subtract, Int, Si, MP(sub_ui), MP(add_ui))
|
||||
@ -476,6 +474,131 @@ namespace MPIR
|
||||
DEFINE_TERNARY_ASSIGNMENT_REF_REF_REF(PowerMod, Int, MP(powm));
|
||||
DEFINE_TERNARY_ASSIGNMENT_REF_VAL_REF(PowerMod, Int, Ui, Int, MP(powm_ui))
|
||||
|
||||
#define WHEN_IS_DEST(i, a) \
|
||||
auto x##i = dynamic_cast<MPTYPE^>(a); \
|
||||
if (!IS_NULL(x##i) && x##i->_value == destination)
|
||||
|
||||
#define WHEN_IS(i, a, atype) \
|
||||
auto x##i = dynamic_cast<MPEXPR(atype)^>(a); \
|
||||
if (!IS_NULL(x##i))
|
||||
|
||||
DEFINE_ASSIGNMENT_PROLOG(AddIntInt)
|
||||
{
|
||||
WHEN_IS_DEST(1, Left)
|
||||
{
|
||||
WHEN_IS(2, Right, MultiplyIntInt)
|
||||
{
|
||||
IN_CONTEXT(x2->Left, x2->Right);
|
||||
MP(addmul)(destination, CTXT(0), CTXT(1));
|
||||
return;
|
||||
}
|
||||
WHEN_IS(3, Right, MultiplyIntUi)
|
||||
{
|
||||
IN_CONTEXT(x3->Left);
|
||||
MP(addmul_ui)(destination, CTXT(0), x3->Right);
|
||||
return;
|
||||
}
|
||||
WHEN_IS(4, Right, MultiplyIntSi)
|
||||
{
|
||||
IN_CONTEXT(x4->Left);
|
||||
auto si = x4->Right;
|
||||
if (si < 0)
|
||||
MP(submul_ui)(destination, CTXT(0), (mpir_ui)-si);
|
||||
else
|
||||
MP(addmul_ui)(destination, CTXT(0), (mpir_ui)si);
|
||||
return;
|
||||
}
|
||||
}
|
||||
WHEN_IS_DEST(5, Right)
|
||||
{
|
||||
WHEN_IS(6, Left, MultiplyIntInt)
|
||||
{
|
||||
IN_CONTEXT(x6->Left, x6->Right);
|
||||
MP(addmul)(destination, CTXT(0), CTXT(1));
|
||||
return;
|
||||
}
|
||||
WHEN_IS(7, Left, MultiplyIntUi)
|
||||
{
|
||||
IN_CONTEXT(x7->Left);
|
||||
MP(addmul_ui)(destination, CTXT(0), x7->Right);
|
||||
return;
|
||||
}
|
||||
WHEN_IS(8, Left, MultiplyIntSi)
|
||||
{
|
||||
IN_CONTEXT(x8->Left);
|
||||
auto si = x8->Right;
|
||||
if (si < 0)
|
||||
MP(submul_ui)(destination, CTXT(0), (mpir_ui)-si);
|
||||
else
|
||||
MP(addmul_ui)(destination, CTXT(0), (mpir_ui)si);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
IN_CONTEXT(Left, Right);
|
||||
MP(add)(destination, CTXT(0), CTXT(1));
|
||||
}
|
||||
|
||||
DEFINE_ASSIGNMENT_PROLOG(SubtractIntInt)
|
||||
{
|
||||
WHEN_IS_DEST(1, Left)
|
||||
{
|
||||
WHEN_IS(2, Right, MultiplyIntInt)
|
||||
{
|
||||
IN_CONTEXT(x2->Left, x2->Right);
|
||||
MP(submul)(destination, CTXT(0), CTXT(1));
|
||||
return;
|
||||
}
|
||||
WHEN_IS(3, Right, MultiplyIntUi)
|
||||
{
|
||||
IN_CONTEXT(x3->Left);
|
||||
MP(submul_ui)(destination, CTXT(0), x3->Right);
|
||||
return;
|
||||
}
|
||||
WHEN_IS(4, Right, MultiplyIntSi)
|
||||
{
|
||||
IN_CONTEXT(x4->Left);
|
||||
auto si = x4->Right;
|
||||
if (si < 0)
|
||||
MP(addmul_ui)(destination, CTXT(0), (mpir_ui)-si);
|
||||
else
|
||||
MP(submul_ui)(destination, CTXT(0), (mpir_ui)si);
|
||||
return;
|
||||
}
|
||||
}
|
||||
WHEN_IS_DEST(5, Right)
|
||||
{
|
||||
WHEN_IS(6, Left, MultiplyIntInt)
|
||||
{
|
||||
IN_CONTEXT(x6->Left, x6->Right);
|
||||
MP(submul)(destination, CTXT(0), CTXT(1));
|
||||
MP(neg)(destination, destination);
|
||||
return;
|
||||
}
|
||||
WHEN_IS(7, Left, MultiplyIntUi)
|
||||
{
|
||||
IN_CONTEXT(x7->Left);
|
||||
MP(submul_ui)(destination, CTXT(0), x7->Right);
|
||||
MP(neg)(destination, destination);
|
||||
return;
|
||||
}
|
||||
WHEN_IS(8, Left, MultiplyIntSi)
|
||||
{
|
||||
IN_CONTEXT(x8->Left);
|
||||
auto si = x8->Right;
|
||||
if (si < 0)
|
||||
MP(addmul_ui)(destination, CTXT(0), (mpir_ui)-si);
|
||||
else
|
||||
MP(submul_ui)(destination, CTXT(0), (mpir_ui)si);
|
||||
MP(neg)(destination, destination);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
IN_CONTEXT(Left, Right);
|
||||
MP(sub)(destination, CTXT(0), CTXT(1));
|
||||
}
|
||||
|
||||
mpir_ui MPEXPR_NAME::Mod(mpir_ui d, RoundingModes rounding)
|
||||
{
|
||||
IN_CONTEXT(this);
|
||||
|
Loading…
Reference in New Issue
Block a user