Float arithmetic and comparison tests

This commit is contained in:
Alex Dyachenko 2014-06-13 11:21:35 -04:00
parent 45071bb9d1
commit 60da57e24c
6 changed files with 2245 additions and 1237 deletions

View File

@ -0,0 +1,347 @@
/*
Copyright 2014 Alex Dyachenko
This file is part of the MPIR Library.
The MPIR Library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published
by the Free Software Foundation; either version 3 of the License, or (at
your option) any later version.
The MPIR Library is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
License for more details.
You should have received a copy of the GNU Lesser General Public License
along with the MPIR Library. If not, see http://www.gnu.org/licenses/.
*/
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace MPIR.Tests.HugeFloatTests
{
public static class FloatAssert
{
public static void AreEqual(string expected, HugeFloat actual)
{
var actualStr = actual.ToString();
if(expected[0] == '-')
{
Assert.AreEqual(expected[0], actualStr[0]);
actualStr = actualStr.TrimStart('-');
expected = expected.TrimStart('-');
}
var exponent = expected.IndexOf('.');
expected = expected.Replace(".", "");
var exponentStr = "@" + exponent;
Assert.IsTrue(actualStr.StartsWith("0."));
actualStr = actualStr.Substring(2);
Assert.IsTrue(actualStr.EndsWith(exponentStr));
actualStr = actualStr.Substring(0, actualStr.Length - exponentStr.Length);
if (expected.Length > actualStr.Length)
{
var roundedUp = expected[actualStr.Length] >= '5';
expected = expected.Substring(0, actualStr.Length);
if(roundedUp)
{
using (var a = new HugeInt(expected))
{
a.Value += 1;
expected = a.ToString(10);
}
}
}
Assert.AreEqual(expected, actualStr);
}
}
[TestClass]
public class Arithmetic
{
#region Add
[TestMethod]
public void FloatAddHugeFloat()
{
using (var a = new HugeFloat("22250983250345029834502983.5740293845720"))
using (var b = new HugeFloat("2229874359879827.30594288574029879874539"))
using (var c = new HugeFloat(a + b))
{
FloatAssert.AreEqual("22250983252574904194382810.87997227031229879874539", c);
c.Value = a + (b + 1);
FloatAssert.AreEqual("22250983252574904194382811.87997227031229879874539", c);
}
}
[TestMethod]
public void FloatAddLimb()
{
using (var a = new HugeFloat("22250983250345029834502983.5740293845720"))
using (var c = new HugeFloat())
{
var b = 4288574029879874539UL;
c.Value = a + b;
FloatAssert.AreEqual("22250987538919059714377522.5740293845720", c);
c.Value = b + a;
FloatAssert.AreEqual("22250987538919059714377522.5740293845720", c);
}
}
[TestMethod]
public void FloatAddSignedLimb()
{
using (var a = new HugeFloat("22250983250345029834502983.5740293845720"))
using (var c = new HugeFloat())
{
var b = -4288574029879874539;
c.Value = a + b;
FloatAssert.AreEqual("22250978961770999954628444.5740293845720", c);
c.Value = b + a;
FloatAssert.AreEqual("22250978961770999954628444.5740293845720", c);
}
}
#endregion
#region Subtract
[TestMethod]
public void FloatSubtractHugeFloat()
{
using (var a = new HugeFloat("22250983250345029834502983.5740293845720"))
using (var b = new HugeFloat("2229874359879827.30594288574029879874539"))
using (var c = new HugeFloat(a - b))
{
FloatAssert.AreEqual("22250983248115155474623156.26808649883170120125461", c);
c.Value = b - (a + 1);
FloatAssert.AreEqual("-22250983248115155474623157.26808649883170120125461", c);
}
}
[TestMethod]
public void FloatSubtractLimb()
{
using(var a = new HugeFloat("22250983250345029834502983.5740293845720"))
using(var c = new HugeFloat())
{
var b = 4288574029879874539UL;
c.Value = a - b;
FloatAssert.AreEqual("22250978961770999954628444.5740293845720", c);
c.Value = b - a;
FloatAssert.AreEqual("-22250978961770999954628444.5740293845720", c);
}
}
[TestMethod]
public void FloatSubtractSignedLimb()
{
using(var a = new HugeFloat("22250983250345029834502983.5740293845720"))
using(var c = new HugeFloat())
{
var b = -4288574029879874539;
c.Value = a - b;
FloatAssert.AreEqual("22250987538919059714377522.5740293845720", c);
c.Value = b - a;
FloatAssert.AreEqual("-22250987538919059714377522.5740293845720", c);
}
}
#endregion
#region Multiply
[TestMethod]
public void FloatMultiplyByHugeFloat()
{
using (var a = new HugeFloat("90234098723098475098479385.345098345"))
using (var b = new HugeFloat("78594873598734.59872354987610987897"))
using (var c = new HugeFloat(a * b))
{
FloatAssert.AreEqual("7091937583437663707014199538801620613535.95657143399816050772069730465", c);
c.Value = b * (a + 1);
FloatAssert.AreEqual("7091937583437663707014199617396494212270.55529498387427038669069730465", c);
}
}
[TestMethod]
public void FloatMultiplyByLimb()
{
using (var a = new HugeFloat("9023409872309847509847.9385345098345"))
using (var c = new HugeFloat())
{
ulong b = 17390538260286101342;
c.Value = a * b;
FloatAssert.AreEqual("156921954622647727368660197878904460649174.746962647899", c);
c.Value = b * -a;
FloatAssert.AreEqual("-156921954622647727368660197878904460649174.746962647899", c);
}
}
[TestMethod]
public void FloatMultiplyBySignedLimb()
{
using (var a = new HugeFloat("9023409872309847509847.9385345098345"))
using (var c = new HugeFloat())
{
long b = -7390538260286101342;
c.Value = a * b;
FloatAssert.AreEqual("-66687855899549252270180812533806115649174.746962647899", c);
c.Value = b * -a;
FloatAssert.AreEqual("66687855899549252270180812533806115649174.746962647899", c);
}
}
#endregion
#region Shift Left
[TestMethod]
public void FloatShiftLeft()
{
using (var a = new HugeFloat("-12345700987ABA245230948.17607EF", 16))
using (var e = new HugeFloat("-12345700987ABA24523094817607.EF", 16))
{
ulong b = 20;
a.Value = a << b;
Assert.AreEqual(e, a);
}
}
#endregion
#region Shift Right
[TestMethod]
public void FloatShiftRight()
{
using (var a = new HugeFloat("-12345700987ABA24523094817607.EF", 16))
using (var e = new HugeFloat("-12345700987ABA245230948.17607EF", 16))
{
ulong b = 20;
a.Value = a >> b;
Assert.AreEqual(e, a);
}
}
#endregion
#region Negate
[TestMethod]
public void FloatNegate()
{
using(var a = new HugeFloat("9023409872309847509847.9385345098345"))
{
a.Value = -a;
FloatAssert.AreEqual("-9023409872309847509847.9385345098345", a);
a.Value = -a;
FloatAssert.AreEqual("9023409872309847509847.9385345098345", a);
}
}
#endregion
#region Abs
[TestMethod]
public void FloatMakeAbsolute()
{
using(var a = new HugeFloat("-9023409872309847509847.9385345098345"))
{
a.Value = a.Abs();
FloatAssert.AreEqual("9023409872309847509847.9385345098345", a);
a.Value = a.Abs();
FloatAssert.AreEqual("9023409872309847509847.9385345098345", a);
}
}
#endregion
#region Power
[TestMethod]
public void FloatPower()
{
using(var a = new HugeFloat("-902340.945098345"))
{
a.Value = a ^ 5;
FloatAssert.AreEqual("-598209523815275040074985233466.4619735146023546465747916785912044", a);
}
}
#endregion
#region Divide
#region Int
[TestMethod]
public void FloatDivideHugeFloat()
{
using (var a = new HugeFloat("1157569866683036578989624354347957.394580293847"))
using (var b = new HugeFloat("593169091750307653294.549782395235784"))
{
a.Value = a / b;
FloatAssert.AreEqual("1951500647593.2689953514865540344827449639493356367018584357", a);
}
}
#endregion
#region Limb
[TestMethod]
public void FloatDivideLimb()
{
using (var a = new HugeFloat("1157569866683036578989624354347957.394580293847"))
{
ulong b = 5931690917503076532;
a.Value = a / b;
FloatAssert.AreEqual("195150064759326.89956625512472902395197480398952074748799190", a);
}
}
[TestMethod]
public void FloatDivideSignedLimb()
{
using(var a = new HugeFloat("1157569866683036578989624354347957.394580293847"))
{
long b = -5931690917503076532;
a.Value = a / b;
FloatAssert.AreEqual("-195150064759326.89956625512472902395197480398952074748799190", a);
}
}
[TestMethod]
public void FloatDivideLimbBy()
{
using(var a = new HugeFloat("11575698666830.39458029384723405203984572"))
{
ulong b = 5931690917503076532;
a.Value = b / a;
FloatAssert.AreEqual("512426.16866833708737257760720580856722540469109813901673959", a);
}
}
[TestMethod]
public void FloatDivideSignedLimbBy()
{
using(var a = new HugeFloat("11575698666830.39458029384723405203984572"))
{
long b = -5931690917503076532;
a.Value = b / a;
FloatAssert.AreEqual("-512426.16866833708737257760720580856722540469109813901673959", a);
}
}
#endregion
#endregion
}
}

View File

@ -0,0 +1,615 @@
/*
Copyright 2014 Alex Dyachenko
This file is part of the MPIR Library.
The MPIR Library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published
by the Free Software Foundation; either version 3 of the License, or (at
your option) any later version.
The MPIR Library is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
License for more details.
You should have received a copy of the GNU Lesser General Public License
along with the MPIR Library. If not, see http://www.gnu.org/licenses/.
*/
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace MPIR.Tests.HugeFloatTests
{
[TestClass]
public class Comparisons
{
#region CompareTo
[TestMethod]
public void FloatCompareToHugeFloat()
{
using (var a = new HugeFloat("-22250983250345029834503.9835740293845721345345354"))
using (var b = new HugeFloat("22250983250345029834502.9835740293845721345345354"))
{
Assert.AreEqual(1, Math.Sign(b.CompareTo(a)));
Assert.AreEqual(-1,Math.Sign(a.CompareTo(b + 1)));
Assert.AreEqual(0, Math.Sign((a + 1).CompareTo(-b)));
Assert.AreEqual(1, Math.Sign(a.CompareTo(null)));
}
}
[TestMethod]
public void FloatCompareToObject()
{
using (var a = new HugeFloat("-22250983250345029834503.9835740293845721345345354"))
using (var b = new HugeFloat("22250983250345029834502.9835740293845721345345354"))
{
Assert.AreEqual(1, Math.Sign(((IComparable)b).CompareTo((object)a)));
Assert.AreEqual(-1,Math.Sign(((IComparable)a).CompareTo((object)b)));
Assert.AreEqual(1, Math.Sign(((IComparable)a).CompareTo(null)));
Assert.AreEqual(0, Math.Sign(((IComparable)(a + 1)).CompareTo((object)-b)));
}
}
[TestMethod]
public void FloatCompareToExpression()
{
using (var a = new HugeFloat("-22250983250345029834503.9835740293845721345345354"))
using (var b = new HugeFloat("22250983250345029834502.9835740293845721345345354"))
{
Assert.AreEqual(1, Math.Sign(((IComparable<FloatExpression>)b).CompareTo(a)));
Assert.AreEqual(-1,Math.Sign(((IComparable<FloatExpression>)a).CompareTo(b)));
Assert.AreEqual(1, Math.Sign(((IComparable<FloatExpression>)a).CompareTo(null)));
Assert.AreEqual(0, Math.Sign(((IComparable<FloatExpression>)(a + 1)).CompareTo(-b)));
}
}
[TestMethod]
[ExpectedException(typeof(ArgumentException))]
public void FloatCompareToNonExpression()
{
using (var a = new HugeFloat("-222509832503450298345029835740293845721.57898962467957"))
{
a.CompareTo("abc");
}
}
[TestMethod]
public void FloatCompareToLimb()
{
using (var a = new HugeFloat("-222509821"))
{
ulong b = 222509820;
Assert.AreEqual(-1,Math.Sign(a.CompareTo(b)));
Assert.AreEqual(-1,Math.Sign(a.CompareTo(b + 1)));
Assert.AreEqual(0, Math.Sign((-(a + 1)).CompareTo(b)));
Assert.AreEqual(0, Math.Sign((-a).CompareTo(b + 1)));
Assert.AreEqual(1, Math.Sign((-a).CompareTo(b)));
}
}
[TestMethod]
public void FloatCompareToSignedLimb()
{
using (var a = new HugeFloat("-222509821"))
{
long b = -222509820;
Assert.AreEqual(-1,Math.Sign(a.CompareTo(b)));
Assert.AreEqual(-1,Math.Sign(a.CompareTo(b + 1)));
Assert.AreEqual(0, Math.Sign((a + 1).CompareTo(b)));
Assert.AreEqual(0, Math.Sign(a.CompareTo(b - 1)));
Assert.AreEqual(1, Math.Sign(a.CompareTo(b - 2)));
}
}
[TestMethod]
public void FloatCompareToSignedDouble()
{
using (var a = new HugeFloat("-222509821"))
{
double b = -222509820;
Assert.AreEqual(-1,Math.Sign(a.CompareTo(b)));
Assert.AreEqual(-1,Math.Sign(a.CompareTo(b + 1)));
Assert.AreEqual(0, Math.Sign((a + 1).CompareTo(b)));
Assert.AreEqual(0, Math.Sign(a.CompareTo(b - 1)));
Assert.AreEqual(1, Math.Sign(a.CompareTo(b - 1.1)));
}
}
#endregion
#region comparison operators with expr
[TestMethod]
public void FloatOperatorLessThan()
{
using (var a = new HugeFloat("-2225098325034502983450.29835740293845721"))
using (var b = new HugeFloat("2225098325034502983450.29835740293845721"))
using (var c = new HugeFloat())
{
c.Value = a;
Assert.IsTrue(a < b);
Assert.IsFalse(b < a);
Assert.IsFalse(a < c);
Assert.IsFalse(a > c);
Assert.IsFalse(a < null);
Assert.IsTrue(null < a);
}
}
[TestMethod]
public void FloatOperatorLessThanOrEqual()
{
using (var a = new HugeFloat("-2225098325034502983451.29835740293845721"))
using (var b = new HugeFloat("2225098325034502983450.29835740293845721"))
using (var c = new HugeFloat())
{
c.Value = a;
Assert.IsTrue(a <= b);
Assert.IsFalse(b <= a);
Assert.IsTrue(a <= c);
Assert.IsFalse(a <= null);
Assert.IsTrue(null <= a);
}
}
[TestMethod]
public void FloatOperatorGreaterThan()
{
using (var a = new HugeFloat("-2225098325034502983451.29835740293845721"))
using (var b = new HugeFloat("2225098325034502983450.29835740293845721"))
using (var c = new HugeFloat())
{
c.Value = a;
Assert.IsFalse(a > b);
Assert.IsTrue(b > a);
Assert.IsFalse(a > c);
Assert.IsTrue(a > null);
Assert.IsFalse(null > a);
}
}
[TestMethod]
public void FloatOperatorGreaterThanOrEqual()
{
using (var a = new HugeFloat("-2225098325034502983451.29835740293845721"))
using (var b = new HugeFloat("2225098325034502983450.29835740293845721"))
using (var c = new HugeFloat())
{
c.Value = a;
Assert.IsFalse(a >= b);
Assert.IsTrue(b >= a);
Assert.IsTrue(a >= c);
Assert.IsTrue(a >= null);
Assert.IsFalse(null >= a);
}
}
#endregion
#region comparison operators with limb
[TestMethod]
public void FloatOperatorLessThanLimb()
{
using (var a = new HugeFloat("3845721"))
{
ulong c = 5432;
ulong b = 5432349587;
Assert.IsTrue(a < b);
Assert.IsFalse(b < a);
Assert.IsFalse(a < c);
Assert.IsTrue(c < a);
}
}
[TestMethod]
public void FloatOperatorLessThanOrEqualLimb()
{
using (var a = new HugeFloat("3845721"))
{
ulong c = 5432;
ulong b = 5432349587;
ulong d = 3845721;
Assert.IsTrue(a <= b);
Assert.IsFalse(b <= a);
Assert.IsFalse(a <= c);
Assert.IsTrue(c <= a);
Assert.IsTrue(a <= d);
Assert.IsTrue(d <= a);
}
}
[TestMethod]
public void FloatOperatorGreaterThanLimb()
{
using (var a = new HugeFloat("3845721"))
{
ulong c = 5432;
ulong b = 5432349587;
Assert.IsFalse(a > b);
Assert.IsTrue(b > a);
Assert.IsTrue(a > c);
Assert.IsFalse(c > a);
}
}
[TestMethod]
public void FloatOperatorGreaterThanOrEqualLimb()
{
using (var a = new HugeFloat("3845721"))
{
ulong c = 5432;
ulong b = 5432349587;
ulong d = 3845721;
Assert.IsFalse(a >= b);
Assert.IsTrue(b >= a);
Assert.IsTrue(a >= c);
Assert.IsFalse(c >= a);
Assert.IsTrue(a >= d);
Assert.IsTrue(d >= a);
}
}
#endregion
#region comparison operators with signed limb
[TestMethod]
public void FloatOperatorLessThanSignedLimb()
{
using (var a = new HugeFloat("-3845721"))
{
long c = -543254325432;
long b = -9587;
Assert.IsTrue(a < b);
Assert.IsFalse(b < a);
Assert.IsFalse(a < c);
Assert.IsTrue(c < a);
}
}
[TestMethod]
public void FloatOperatorLessThanOrEqualSignedLimb()
{
using (var a = new HugeFloat("-3845721"))
{
long c = -543254325432;
long b = -9587;
long d = -3845721;
Assert.IsTrue(a <= b);
Assert.IsFalse(b <= a);
Assert.IsFalse(a <= c);
Assert.IsTrue(c <= a);
Assert.IsTrue(a <= d);
Assert.IsTrue(d <= a);
}
}
[TestMethod]
public void FloatOperatorGreaterThanSignedLimb()
{
using (var a = new HugeFloat("-3845721"))
{
long c = -543254325432;
long b = -9587;
Assert.IsFalse(a > b);
Assert.IsTrue(b > a);
Assert.IsTrue(a > c);
Assert.IsFalse(c > a);
}
}
[TestMethod]
public void FloatOperatorGreaterThanOrEqualSignedLimb()
{
using (var a = new HugeFloat("-3845721"))
{
long c = -543254325432;
long b = -9587;
long d = -3845721;
Assert.IsFalse(a >= b);
Assert.IsTrue(b >= a);
Assert.IsTrue(a >= c);
Assert.IsFalse(c >= a);
Assert.IsTrue(a >= d);
Assert.IsTrue(d >= a);
}
}
#endregion
#region comparison operators with double
[TestMethod]
public void FloatOperatorLessThanDouble()
{
using (var a = new HugeFloat("-3845721"))
{
double c = -543254325432;
double b = -9587;
Assert.IsTrue(a < b);
Assert.IsFalse(b < a);
Assert.IsFalse(a < c);
Assert.IsTrue(c < a);
}
}
[TestMethod]
public void FloatOperatorLessThanOrEqualDouble()
{
using (var a = new HugeFloat("-3845721"))
{
double c = -543254325432;
double b = -9587;
double d = -3845721;
Assert.IsTrue(a <= b);
Assert.IsFalse(b <= a);
Assert.IsFalse(a <= c);
Assert.IsTrue(c <= a);
Assert.IsTrue(a <= d);
Assert.IsTrue(d <= a);
}
}
[TestMethod]
public void FloatOperatorGreaterThanDouble()
{
using (var a = new HugeFloat("-3845721"))
{
double c = -543254325432;
double b = -9587;
Assert.IsFalse(a > b);
Assert.IsTrue(b > a);
Assert.IsTrue(a > c);
Assert.IsFalse(c > a);
}
}
[TestMethod]
public void FloatOperatorGreaterThanOrEqualDouble()
{
using (var a = new HugeFloat("-3845721"))
{
double c = -543254325432;
double b = -9587;
double d = -3845721;
Assert.IsFalse(a >= b);
Assert.IsTrue(b >= a);
Assert.IsTrue(a >= c);
Assert.IsFalse(c >= a);
Assert.IsTrue(a >= d);
Assert.IsTrue(d >= a);
Assert.IsFalse(d - 0.1 >= a);
}
}
#endregion
#region Equals
[TestMethod]
public void FloatEqualsHugeFloat()
{
using (var a = new HugeFloat("-2225098325034502983451.29835740293845721"))
using (var b = new HugeFloat("2225098325034502983450.29835740293845721"))
{
Assert.IsFalse(b.Equals(a));
Assert.IsFalse(a.Equals(b + 1));
Assert.IsTrue((a + 1).Equals(-b));
Assert.IsFalse(a.Equals(null));
Assert.IsTrue(Equals(a + 1, -b));
}
}
[TestMethod]
public void FloatEqualsExpression()
{
using (var a = new HugeFloat("-2225098325034502983451.29835740293845721"))
using (var b = new HugeFloat("2225098325034502983450.29835740293845721"))
{
Assert.IsFalse(((IEquatable<FloatExpression>)b).Equals(a));
Assert.IsFalse(((IEquatable<FloatExpression>)a).Equals(b));
Assert.IsFalse(((IEquatable<FloatExpression>)a).Equals(null));
Assert.IsTrue(((IEquatable<FloatExpression>)(a + 1)).Equals(-b));
}
}
[TestMethod]
public void FloatEqualsNonExpression()
{
using (var a = new HugeFloat("-2225098325034502983450.29835740293845721"))
{
Assert.IsFalse(a.Equals("abc"));
}
}
[TestMethod]
public void FloatEqualsLimb()
{
using (var a = new HugeFloat("222509832503"))
{
ulong b = 222509832504;
Assert.IsFalse(a.Equals(b + 1));
Assert.IsTrue(a.Equals(b - 1));
Assert.IsTrue((a + 1).Equals(b));
}
}
[TestMethod]
public void FloatEqualsSignedLimb()
{
using (var a = new HugeFloat("-222509832505"))
{
long b = -222509832504;
Assert.IsFalse(a.Equals(b + 1));
Assert.IsTrue(a.Equals(b - 1));
Assert.IsTrue((a + 1).Equals(b));
}
}
[TestMethod]
public void FloatEqualsDouble()
{
using (var a = new HugeFloat("-222509832505"))
{
double b = -222509832504;
Assert.IsFalse(a.Equals(b + 1));
Assert.IsTrue(a.Equals(b - 1));
Assert.IsTrue((a + 1).Equals(b));
Assert.IsFalse((a + 1).Equals(b + 0.1));
}
}
#endregion
#region Equality operators with expr
[TestMethod]
public void FloatEqualsOperatorHugeFloat()
{
using (var a = new HugeFloat("-2225098325034502983451.29835740293845721"))
using (var b = new HugeFloat("2225098325034502983450.29835740293845721"))
{
Assert.IsFalse(b == a);
Assert.IsFalse(a == b + 1);
Assert.IsTrue(a + 1 == -b);
Assert.IsFalse(a == null);
}
}
[TestMethod]
public void FloatNotEqualOperatorHugeFloat()
{
using (var a = new HugeFloat("-2225098325034502983451.29835740293845721"))
using (var b = new HugeFloat("2225098325034502983450.29835740293845721"))
{
Assert.IsTrue(b != a);
Assert.IsTrue(a != b + 1);
Assert.IsFalse(a + 1 != -b);
Assert.IsTrue(a != null);
}
}
#endregion
#region Equality operators with Limb
[TestMethod]
public void FloatEqualsOperatorLimb()
{
using (var a = new HugeFloat("-835740293845721"))
{
ulong b = 835740293845720;
Assert.IsFalse(b == a);
Assert.IsFalse(a == b + 1);
Assert.IsTrue(-(a + 1) == b);
}
}
[TestMethod]
public void FloatNotEqualOperatorLimb()
{
using (var a = new HugeFloat("-835740293845721"))
{
ulong b = 835740293845720;
Assert.IsTrue(b != a);
Assert.IsTrue(a != b + 1);
Assert.IsFalse(-(a + 1) != b);
}
}
#endregion
#region Equality operators with Signed Limb
[TestMethod]
public void FloatEqualsOperatorSignedLimb()
{
using (var a = new HugeFloat("-835740293845721"))
{
long b = -835740293845720;
Assert.IsFalse(b == a);
Assert.IsFalse(a == b + 1);
Assert.IsTrue(a + 1 == b);
}
}
[TestMethod]
public void FloatNotEqualOperatorSignedLimb()
{
using (var a = new HugeFloat("-835740293845721"))
{
long b = -835740293845720;
Assert.IsTrue(b != a);
Assert.IsTrue(a != b + 1);
Assert.IsFalse(a + 1 != b);
}
}
#endregion
#region Equality operators with Double
[TestMethod]
public void FloatEqualsOperatorDouble()
{
using (var a = new HugeFloat("-835740293845721"))
{
double b = -835740293845720;
Assert.IsFalse(b == a);
Assert.IsFalse(a == b + 1);
Assert.IsTrue(a + 1 == b);
Assert.IsFalse(a + 1 == b + 0.1);
}
}
[TestMethod]
public void FloatNotEqualOperatorDouble()
{
using (var a = new HugeFloat("-835740293845721"))
{
double b = -835740293845720;
Assert.IsTrue(b != a);
Assert.IsTrue(a != b + 1);
Assert.IsFalse(a + 1 != b);
Assert.IsTrue(a + 1 != b + 0.1);
}
}
#endregion
#region GetHashCode
[TestMethod]
public void FloatGetHashCodeTest()
{
using (var a = new HugeFloat("-2225098325034502983450298357.40293845721"))
{
Assert.AreNotEqual(0, a.GetHashCode());
Assert.AreEqual(a.GetHashCode(), (a + 0).GetHashCode());
Assert.AreNotEqual(a.GetHashCode(), (-a).GetHashCode());
}
}
#endregion
#region Sign
[TestMethod]
public void FloatSign()
{
using (var a = new HugeFloat("-22250983250345029834.502983574029384572134354"))
{
Assert.AreEqual(-1, a.Sign());
Assert.AreEqual(1, (-a).Sign());
Assert.AreEqual(0, (a-a).Sign());
}
}
#endregion
//more tests coming here
}
}

View File

@ -157,6 +157,8 @@
<Compile Include="..\..\..\mpir.net\mpir.net-tests\Properties\AssemblyInfo.cs">
<Link>Properties\AssemblyInfo.cs</Link>
</Compile>
<Compile Include="HugeFloatTests\Arithmetic.cs" />
<Compile Include="HugeFloatTests\Comparisons.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\mpir.net\mpir.net.vcxproj">
@ -164,9 +166,7 @@
<Name>mpir.net</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Folder Include="HugeFloatTests\" />
</ItemGroup>
<ItemGroup />
<Choose>
<When Condition="'$(VisualStudioVersion)' == '10.0' And '$(IsCodedUITest)' == 'True'">
<ItemGroup>

View File

@ -54,7 +54,7 @@ namespace MPIR.Tests.RandomTests
break;
case 4:
r.Seed(seed); //r = copy; temporarily disabled copy tests due to MPIR bug
r.Seed(seed); //todo r = copy; temporarily disabled copy tests due to MPIR bug
break;
}

View File

@ -113,10 +113,39 @@ namespace MPIR
String^ MPTYPE::ToString(int base, bool lowercase, int maxDigits)
{
auto result = gcnew StringBuilder();
//result->Append(this->Numerator->ToString(base, lowercase, maxDigits));
//result->Append((wchar_t)'/');
//result->Append(this->Denominator->ToString(base, lowercase, maxDigits));
if(base < 2 || base > 62)
throw gcnew ArgumentOutOfRangeException("base", "Invalid base");
mp_exp_t exponent;
auto allocatedStr = MP(get_str)(NULL, &exponent, (!lowercase && base <= 36) ? -base : base, maxDigits, _value);
auto str = allocatedStr;
auto result = maxDigits > 0 ? gcnew StringBuilder(maxDigits + 70) : gcnew StringBuilder();
size_t allocated = 1;
if (*str == '-')
{
result->Append((wchar_t)'-');
allocated++;
str++;
}
result->Append((wchar_t)'0');
if (*str != 0)
{
result->Append((wchar_t)'.');
while (*str != 0)
{
result->Append((wchar_t)*str);
allocated++;
str++;
}
result->Append((wchar_t)'@');
result->Append(exponent);
}
(*__gmp_free_func)(allocatedStr, allocated);
return result->ToString();
}

View File

@ -726,12 +726,15 @@ namespace MPIR
internal:
//fields
MP(ptr) _value;
mp_bitcnt_t _allocatedPrecision;
private:
//construction
void AllocateStruct()
{
_value = (MP(ptr))((*__gmp_allocate_func)(sizeof(MPSTRUCT)));
//todo: move this to wherever init is called
_allocatedPrecision = MP(get_prec)(_value);
}
void FromString(String^ value, int base);
MPTYPE(bool initialize);
@ -740,6 +743,7 @@ namespace MPIR
internal:
virtual void DeallocateStruct()
{
MP(set_prec_raw)(_value, _allocatedPrecision);
MP(clear)(_value);
(*__gmp_free_func)(_value, sizeof(MPSTRUCT));
_value = nullptr;
@ -759,6 +763,17 @@ namespace MPIR
public:
#pragma region construction and disposal
static MPTYPE()
{
DefaultPrecision = sizeof(mpir_ui) * 8 * 2; //2 limbs
}
static property mp_bitcnt_t DefaultPrecision
{
mp_bitcnt_t get() { return MP(get_default_prec)(); }
void set(mp_bitcnt_t value) { MP(set_default_prec)(value); }
}
/// <summary>
/// Initializes a new float instance and sets its value to 0/1
/// </summary>
@ -889,14 +904,16 @@ namespace MPIR
/// <summary>
/// Returns the value of the number as a double, truncating if necessary (rounding towards zero).
/// <para>If the exponent from the conversion is too big, the result is system dependent. An infinity is returned where available. /// A hardware overflow trap may or may not occur.
/// <para>If the exponent from the conversion is too big, the result is system dependent. An infinity is returned where available.
/// A hardware overflow trap may or may not occur.
/// </para></summary>
/// <returns>The value as a double, possibly truncated.</returns>
double ToDouble() { return MP(get_d)(_value); }
///// <summary>
///// Returns the value of the number as a double, truncating if necessary (rounding towards zero), and returning the exponent separately.
///// <para>The return is the mantissa, its absolute value will be in the range [0.5 - 1). ///// </para>If the source value is zero, both mantissa and exponent are returned as 0.
///// <para>The return is the mantissa, its absolute value will be in the range [0.5 - 1).
///// </para>If the source value is zero, both mantissa and exponent are returned as 0.
///// </summary>
///// <param name="exp">variable to store the exponent in.</param>
///// <returns>The mantissa of the value as a double, possibly truncated.</returns>