Float conversion tests and full implementation of ToString()

This commit is contained in:
Alex Dyachenko 2014-06-17 17:53:26 -04:00
parent cc66a187e1
commit f971feae43
5 changed files with 69 additions and 91 deletions

View File

@ -106,6 +106,9 @@
<Compile Include="..\..\..\mpir.net\mpir.net-tests\HugeFloatTests\ConstructionAndDisposal.cs">
<Link>HugeFloatTests\ConstructionAndDisposal.cs</Link>
</Compile>
<Compile Include="..\..\..\mpir.net\mpir.net-tests\HugeFloatTests\Conversions.cs">
<Link>HugeFloatTests\Conversions.cs</Link>
</Compile>
<Compile Include="..\..\..\mpir.net\mpir.net-tests\HugeIntTests\Arithmetic.cs">
<Link>HugeIntTests\Arithmetic.cs</Link>
</Compile>

View File

@ -58,7 +58,7 @@ namespace MPIR.Tests.HugeFloatTests
Assert.AreEqual(128UL, a._allocatedPrecision);
Assert.AreEqual(128UL, a.Precision);
Assert.AreEqual(1, a.Exponent());
Assert.AreEqual("0." + n.ToString("X") + "@16", a.ToString(16));
Assert.AreEqual("0." + n.ToString("X") + "@16", a.ToString(16, false, true));
}
}
@ -71,7 +71,7 @@ namespace MPIR.Tests.HugeFloatTests
Assert.AreEqual(128UL, a._allocatedPrecision);
Assert.AreEqual(128UL, a.Precision);
Assert.AreEqual(1, a.Exponent());
Assert.AreEqual("-0." + n.ToString("X") + "@16", a.ToString(16));
Assert.AreEqual("-0." + n.ToString("X") + "@16", a.ToString(16, false, true));
}
}
@ -84,7 +84,7 @@ namespace MPIR.Tests.HugeFloatTests
Assert.AreEqual(128UL, a._allocatedPrecision);
Assert.AreEqual(128UL, a.Precision);
Assert.AreEqual(1, a.Exponent());
Assert.AreEqual("0." + n.ToString("X") + "@16", a.ToString(16));
Assert.AreEqual("0." + n.ToString("X") + "@16", a.ToString(16, false, true));
}
}
@ -140,7 +140,7 @@ namespace MPIR.Tests.HugeFloatTests
var n = "143210ABCDEF32123457ACDB324.59879";
using (var a = new HugeFloat(n, 16))
{
Assert.AreEqual("0.143210ABCDEF32123457ACDB32459879@27", a.ToString(16));
Assert.AreEqual("0.143210ABCDEF32123457ACDB32459879@27", a.ToString(16, false, true));
}
}

View File

@ -21,70 +21,61 @@ using System;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace MPIR.Tests.HugeRationalTests
namespace MPIR.Tests.HugeFloatTests
{
[TestClass]
public class Conversions
{
[TestMethod]
public void RationalToStringDecimal()
public void FloatToStringDecimal()
{
var n = "-23429384756298357462983476598345623984756";
var d = "115756986668303657898962467957";
var s = n + "/" + d;
using (var a = new HugeRational(s))
var n = "-234293847562.98357462983476598345623984756";
using (var a = new HugeFloat(n))
{
Assert.AreEqual(s, a.ToString());
FloatAssert.AreEqual(n, a);
}
}
[TestMethod]
public void RationalToStringHex()
public void FloatToStringHex()
{
var n = "-23429abcdef298357462983fedcba345623984756";
var d = "17607ef654eb9a13ffa163c75";
var s = n + "/" + d;
using (var a = new HugeRational(s, 16))
var s = "-23429abcdef29835746298.3fedcba34562";
using (var a = new HugeFloat(s, 16))
{
Assert.AreEqual(s, a.ToString(16, true));
Assert.AreEqual(s.ToUpper(), a.ToString(16));
Assert.AreEqual("-0.23429abcdef298357462983fedcba34562@16", a.ToString(16, true));
Assert.AreEqual("-0.23429ABCDEF298357462983FEDCBA34562@16", a.ToString(16));
Assert.AreEqual("-0.23429abcdef298357462983fedcba34562@22", a.ToString(16, true, true));
Assert.AreEqual("-0.23429ABCDEF298357462983FEDCBA34562@22", a.ToString(16, false, true));
}
}
[TestMethod]
public void RationalFromUlong()
public void FloatFromUlong()
{
using (var a = new HugeRational())
using (var a = new HugeFloat())
{
ulong b = 0xF84739ABCDEF4876;
ulong d = 12764787846358441471;
a.SetTo(b, d);
Assert.AreEqual(b.ToString() + "/" + d.ToString(), a.ToString());
a.SetTo(b);
Assert.AreEqual(b.ToString() + "/1", a.ToString());
FloatAssert.AreEqual(b + ".", a);
}
}
[TestMethod]
public void RationalFromLong()
public void FloatFromLong()
{
using (var a = new HugeRational())
using (var a = new HugeFloat())
{
long b = -0x784739ABCDEF4876;
ulong d = 12764787846358441471;
a.SetTo(b, d);
Assert.AreEqual(b.ToString() + "/" + d.ToString(), a.ToString());
a.SetTo(b);
Assert.AreEqual(b.ToString() + "/1", a.ToString());
FloatAssert.AreEqual(b + ".", a);
}
}
[TestMethod]
public void RationalToAndFromDouble()
public void FloatToAndFromDouble()
{
using (var a = new HugeRational())
using (var a = new HugeFloat())
{
a.SetTo(-123.25);
@ -95,9 +86,9 @@ namespace MPIR.Tests.HugeRationalTests
}
[TestMethod]
public void RationalToAndFromFloat()
public void FloatToAndFromFloat()
{
using (var a = new HugeRational())
using (var a = new HugeFloat())
{
a.SetTo(-123.125f);
@ -109,78 +100,40 @@ namespace MPIR.Tests.HugeRationalTests
}
[TestMethod]
public void RationalFromString()
public void FloatFromString()
{
using (var a = new HugeRational())
using (var a = new HugeFloat())
{
var n = "98762934876529834765234123984761/115756986668303657898962467957";
var n = "98762934876529834765234123.984761";
a.SetTo(n);
Assert.AreEqual(n, a.ToString());
n = "-98ABCDEF876529834765234123984761/17607EF654EB9A13FFA163C75";
a.SetTo(n, 16);
Assert.AreEqual(n, a.ToString(16));
n = "-98ABCDEF876529834765234123984761";
a.SetTo(n, 16);
Assert.AreEqual(n + "/1", a.ToString(16));
FloatAssert.AreEqual(n, a);
}
}
[TestMethod]
[ExpectedException(typeof(ArgumentException))]
public void RationalFromInvalidString()
public void FloatFromInvalidString()
{
using (var a = new HugeRational())
using (var a = new HugeFloat())
{
a.SetTo("12345A");
}
}
[TestMethod]
[ExpectedException(typeof(ArgumentException))]
public void RationalFromInvalidString2()
{
using (var a = new HugeRational())
{
a.SetTo("12345/13345A");
}
}
[TestMethod]
public void RationalToStringTruncated()
public void FloatToStringTruncated()
{
using (var d = new HugeInt("115756986668303657898962467957"))
using (var e = new HugeInt(d ^ 10))
{
var s = e.ToString(10);
var n = string.Concat("123456789".Select(c => new string(c, 30)));
using (var a = new HugeRational(n + "/" + s))
using (var a = HugeFloat.Allocate(1200))
{
Assert.AreEqual(n + "/" + s, a.ToString(10));
Assert.AreEqual("..." + n.Substring(n.Length - 256) + "/..." + s.Substring(s.Length - 256), a.ToString());
a.Value = -a;
Assert.AreEqual("-..." + n.Substring(n.Length - 256) + "/..." + s.Substring(s.Length - 256), a.ToString());
a.SetTo(s);
Assert.AreEqual(256, a.ToString().Replace("0.", "").Replace("@291", "").Length);
Assert.AreEqual(291, a.ToString(10).Replace("0.", "").Replace("@291", "").Length);
}
}
}
[TestMethod]
public void RationalApproximateSizeInBase()
{
using (var a = new HugeRational("2983475029834750293429834750298347502934298347502983475029342983475029834750293429834750298347502934/115756986668303657898962467957"))
{
AssertBetween(131, 133, a.ApproximateSizeInBase(10));
AssertBetween(429, 429, a.ApproximateSizeInBase(2));
AssertBetween(109, 109, a.ApproximateSizeInBase(16));
AssertBetween(84, 86, a.ApproximateSizeInBase(36));
AssertBetween(74, 76, a.ApproximateSizeInBase(62));
}
}
private void AssertBetween(int min, int max, long actual)
{
Assert.IsTrue(actual >= min && actual <= max, "Expected {0} to {1}, actual {2}", min, max, actual);
}
}
}

View File

@ -123,7 +123,7 @@ namespace MPIR
#pragma region object overrides
String^ MPTYPE::ToString(int base, bool lowercase, int maxDigits)
String^ MPTYPE::ToString(int base, bool lowercase, int maxDigits, bool exponentInDecimal)
{
if(base < 2 || base > 62)
throw gcnew ArgumentOutOfRangeException("base", "Invalid base");
@ -153,7 +153,16 @@ namespace MPIR
str++;
}
result->Append((wchar_t)'@');
result->Append(exponent);
if(exponentInDecimal)
{
result->Append(exponent);
}
else
{
HugeInt exp((mpir_si) exponent);
result->Append(exp.ToString(base, lowercase));
}
}
(*__gmp_free_func)(allocatedStr, allocated);

View File

@ -763,7 +763,7 @@ namespace MPIR
}
void FromString(String^ value, int base);
MPTYPE(bool initialize);
String^ ToString(int base, bool lowercase, int maxDigits);
String^ ToString(int base, bool lowercase, int maxDigits, bool exponentInDecimal);
internal:
virtual void DeallocateStruct()
@ -896,7 +896,7 @@ namespace MPIR
/// </para>Setting MpirSettings.ToStringDigits to 0 removes the upper limit.
/// </summary>
/// <returns>A string representation of the number in decimal, possibly cut off if the number has more digits than MpirSettings.ToStringDigits.</returns>
virtual String^ ToString() override { return ToString(10, false, MpirSettings::ToStringDigits); }
virtual String^ ToString() override { return ToString(10, false, MpirSettings::ToStringDigits, false); }
/// <summary>
/// Converts the number to a string in the specified base.
@ -904,7 +904,7 @@ namespace MPIR
/// </para></summary>
/// <param name="base">The base to use for the output. The base can be from 2 to 62; uppercase letters represent digits 10-35 and lowercase letters represent digits 36-61.</param>
/// <returns>A string representation of the number in the specified base.</returns>
String^ ToString(int base) { return ToString(base, false, 0); }
String^ ToString(int base) { return ToString(base, false, 0, false); }
/// <summary>
/// Converts the number to a string in the specified base.
@ -916,7 +916,20 @@ namespace MPIR
/// <param name="lowercase">Indicates if lowercase or uppercase letters should be used for the output.
/// <para>This argument is ignored for bases larger than 36, where both uppercase and lowercase letters are used.</para></param>
/// <returns>A string representation of the number in the specified base.</returns>
String^ ToString(int base, bool lowercase) { return ToString(base, lowercase, 0); }
String^ ToString(int base, bool lowercase) { return ToString(base, lowercase, 0, false); }
/// <summary>
/// Converts the number to a string in the specified base.
/// <para>This method always produces the complete output regardless of the MpirSettings.ToStringDigits setting.
/// </para></summary>
/// <param name="base">The base to use for the output.
/// <para>The base can be from 2 to 62; Bases up to 36 use uppercase or lowercase letters based on the <paramref name="lowercase"/> argument.
/// </para>For bases larger than 36, the <paramref name="lowercase"/> argument is ignored and uppercase letters represent digits 10-35 while lowercase letters represent digits 36-61.</param>
/// <param name="lowercase">Indicates if lowercase or uppercase letters should be used for the output.
/// <para>This argument is ignored for bases larger than 36, where both uppercase and lowercase letters are used.</para></param>
/// <param name="exponentInDecimal">True to always show the exponent in decimal, False to use the same base as the mantissa</param>
/// <returns>A string representation of the number in the specified base.</returns>
String^ ToString(int base, bool lowercase, bool exponentInDecimal) { return ToString(base, lowercase, 0, exponentInDecimal); }
///// <summary>
///// Returns the absolute value of the number as a ulong.