451 lines
14 KiB
C#
451 lines
14 KiB
C#
/*
|
|
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 System.Linq;
|
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
|
|
|
namespace MPIR.Tests.HugeFloatTests
|
|
{
|
|
[TestClass]
|
|
public class Conversions
|
|
{
|
|
private static HugeFloat AlmostOne;
|
|
|
|
[ClassInitialize]
|
|
public static void Init(TestContext context)
|
|
{
|
|
AlmostOne = new HugeFloat(0.99999);
|
|
HugeFloat.DefaultPrecision = 128;
|
|
}
|
|
|
|
[ClassCleanup]
|
|
public static void Cleanup()
|
|
{
|
|
HugeFloat.DefaultPrecision = 64;
|
|
}
|
|
|
|
[TestMethod]
|
|
public void FloatToStringDecimal()
|
|
{
|
|
var n = "-234293847562.98357462983476598345623984756";
|
|
using (var a = new HugeFloat(n))
|
|
{
|
|
FloatAssert.AreEqual(n, a);
|
|
}
|
|
}
|
|
|
|
[TestMethod]
|
|
public void FloatToStringHex()
|
|
{
|
|
var s = "-23429abcdef29835746298.3fedcba34562";
|
|
using (var a = new HugeFloat(s, 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 FloatFromUlong()
|
|
{
|
|
using (var a = new HugeFloat())
|
|
{
|
|
var b = Platform.Ui(0xF84739ABCDEF4876, 0xF84739AB);
|
|
a.SetTo(b);
|
|
FloatAssert.AreEqual(b + ".", a);
|
|
}
|
|
}
|
|
|
|
[TestMethod]
|
|
public void FloatFromLong()
|
|
{
|
|
using (var a = new HugeFloat())
|
|
{
|
|
var b = Platform.Si(-0x784739ABCDEF4876, -0x784739AB);
|
|
a.SetTo(b);
|
|
FloatAssert.AreEqual(b + ".", a);
|
|
}
|
|
}
|
|
|
|
[TestMethod]
|
|
public void FloatToAndFromDouble()
|
|
{
|
|
using (var a = new HugeFloat())
|
|
{
|
|
a.SetTo(-123.25);
|
|
|
|
double c = a.ToDouble();
|
|
Assert.IsTrue(c.Equals(-123.25));
|
|
Assert.IsTrue(a.Equals(-123.25));
|
|
Assert.AreEqual("-0.12325@3", a.ToString());
|
|
}
|
|
}
|
|
|
|
[TestMethod]
|
|
public void FloatToAndFromDouble2()
|
|
{
|
|
using (var a = new HugeFloat())
|
|
{
|
|
a.SetTo(-123.25);
|
|
var exp = Platform.Si(0, 0);
|
|
double c = a.ToDouble(out exp);
|
|
Assert.IsTrue(c.Equals(-0.962890625));
|
|
Assert.AreEqual(7L, exp);
|
|
Assert.IsTrue(a.Equals(-123.25));
|
|
Assert.AreEqual("-0.12325@3", a.ToString());
|
|
}
|
|
}
|
|
|
|
[TestMethod]
|
|
public void FloatToAndFromFloat()
|
|
{
|
|
using (var a = new HugeFloat())
|
|
{
|
|
a.SetTo(-123.125f);
|
|
|
|
double c = a.ToDouble();
|
|
Assert.IsTrue(-123.125 == c);
|
|
Assert.IsTrue(-123.125 == a);
|
|
Assert.IsTrue(-123.125f == a);
|
|
}
|
|
}
|
|
|
|
#if WIN64
|
|
[TestMethod]
|
|
public void FloatToAndFromUlong()
|
|
{
|
|
using (var a = new HugeFloat())
|
|
{
|
|
ulong b = 0xF84739ABCDEF4876;
|
|
a.SetTo(b);
|
|
FloatAssert.AreEqual(b + ".", a);
|
|
|
|
a.Value = -a;
|
|
ulong c = a.ToUlong();
|
|
Assert.AreEqual(b, c);
|
|
}
|
|
}
|
|
|
|
[TestMethod]
|
|
public void FloatToAndFromLong()
|
|
{
|
|
using(var a = new HugeFloat())
|
|
{
|
|
long b = -0x784739ABCDEF4876;
|
|
a.SetTo(b);
|
|
FloatAssert.AreEqual(b + ".", a);
|
|
|
|
long c = a.ToLong();
|
|
Assert.AreEqual(b, c);
|
|
}
|
|
}
|
|
#else
|
|
[TestMethod]
|
|
public void FloatToAndFromUint()
|
|
{
|
|
using (var a = new HugeFloat())
|
|
{
|
|
ulong b = 0xF84739AB;
|
|
a.SetTo(b);
|
|
FloatAssert.AreEqual(b + ".", a);
|
|
|
|
a.Value = -a;
|
|
ulong c = a.ToUint();
|
|
Assert.AreEqual(b, c);
|
|
}
|
|
}
|
|
|
|
[TestMethod]
|
|
public void FloatToAndFromInt()
|
|
{
|
|
using (var a = new HugeFloat())
|
|
{
|
|
long b = -0x784739AB;
|
|
a.SetTo(b);
|
|
FloatAssert.AreEqual(b + ".", a);
|
|
|
|
long c = a.ToInt();
|
|
Assert.AreEqual(b, c);
|
|
}
|
|
}
|
|
#endif
|
|
|
|
[TestMethod]
|
|
public void FloatToAndFromDoubleOutExp()
|
|
{
|
|
using(var a = new HugeFloat())
|
|
{
|
|
a.SetTo(-123.45e20);
|
|
var exp = Platform.Si(0, 0);
|
|
var zillion = Platform.Si(10000000000, 1000000000);
|
|
a.Value = a + a;
|
|
double c = a.ToDouble(out exp);
|
|
|
|
Assert.AreEqual(75, exp);
|
|
c *= Math.Pow(2, exp);
|
|
|
|
Assert.IsTrue(a + zillion >= c);
|
|
Assert.IsTrue(a - zillion <= c);
|
|
}
|
|
}
|
|
|
|
#if WIN64
|
|
[TestMethod]
|
|
public void FloatToLong2()
|
|
{
|
|
using (var a = new HugeFloat())
|
|
using (var small = new HugeFloat(0.0001))
|
|
{
|
|
long b = long.MaxValue;
|
|
a.SetTo(b);
|
|
a.Value = a + 1 - small;
|
|
var c = a.ToLong();
|
|
|
|
Assert.AreEqual(b, c);
|
|
|
|
b = long.MinValue;
|
|
a.SetTo(b);
|
|
a.Value -= 1 - small;
|
|
c = a.ToLong();
|
|
Assert.AreEqual(b, c);
|
|
}
|
|
}
|
|
#else
|
|
[TestMethod]
|
|
public void FloatToInt2()
|
|
{
|
|
using (var a = new HugeFloat())
|
|
using (var small = new HugeFloat(0.0001))
|
|
{
|
|
int b = int.MaxValue;
|
|
a.SetTo(b);
|
|
a.Value = a + 1 - small;
|
|
var c = a.ToInt();
|
|
|
|
Assert.AreEqual(b, c);
|
|
|
|
b = int.MinValue;
|
|
a.SetTo(b);
|
|
a.Value -= 1 - small;
|
|
c = a.ToInt();
|
|
Assert.AreEqual(b, c);
|
|
}
|
|
}
|
|
#endif
|
|
|
|
[TestMethod]
|
|
public void FloatFromString()
|
|
{
|
|
using (var a = HugeFloat.Allocate(256))
|
|
{
|
|
var n = "98762934876529834765234123984761";
|
|
a.SetTo(n);
|
|
Assert.AreEqual("0." + n + "@" + n.Length, a.ToString());
|
|
|
|
n = "-98ABCDEF876529834765234123984761";
|
|
a.SetTo(n, 16);
|
|
Assert.AreEqual("-0." + n.Substring(1) + "@" + (n.Length - 1).ToString("x"), a.ToString(16));
|
|
}
|
|
}
|
|
|
|
[TestMethod]
|
|
public void FloatFromStringExpDecimal()
|
|
{
|
|
using(var a = new HugeFloat())
|
|
{
|
|
var n = "0.12354523094527035843ABCDEF54@10";
|
|
|
|
a.SetTo(n, 16);
|
|
Assert.AreEqual("0.12354523094527035843ABCDEF54@10", a.ToString(16, false, true));
|
|
Assert.AreEqual("0.12354523094527035843ABCDEF54@A", a.ToString(16, false, false));
|
|
|
|
a.SetTo(n, 16, false);
|
|
Assert.AreEqual("0.12354523094527035843ABCDEF54@16", a.ToString(16, false, true));
|
|
Assert.AreEqual("0.12354523094527035843ABCDEF54@10", a.ToString(16, false, false));
|
|
}
|
|
}
|
|
|
|
[TestMethod]
|
|
[ExpectedException(typeof(ArgumentException))]
|
|
public void FloatFromInvalidString()
|
|
{
|
|
using (var a = new HugeFloat())
|
|
{
|
|
a.SetTo("12345A");
|
|
}
|
|
}
|
|
|
|
[TestMethod]
|
|
public void FloatToStringTruncated()
|
|
{
|
|
var n = string.Concat("123456783".Select(c => new string(c, 30)));
|
|
using (var a = HugeFloat.Allocate(2000))
|
|
{
|
|
a.SetTo(n);
|
|
Assert.AreEqual("0." + n + "@" + n.Length, a.ToString(10));
|
|
Assert.AreEqual("0." + n.Substring(0, 256) + "@" + n.Length, a.ToString());
|
|
a.Value = -a;
|
|
Assert.AreEqual("-0." + n.Substring(0, 256) + "@" + n.Length, a.ToString());
|
|
}
|
|
}
|
|
|
|
#if WIN64
|
|
[TestMethod]
|
|
public void FloatFitsUlong()
|
|
{
|
|
using (var a = new HugeFloat(ulong.MaxValue))
|
|
using (var small = new HugeFloat(0.0001))
|
|
{
|
|
Assert.IsTrue(a.FitsUlong());
|
|
a.Value = a + 1;
|
|
Assert.IsFalse(a.FitsUlong());
|
|
a.Value = a - small;
|
|
Assert.IsTrue(a.FitsUlong());
|
|
a.SetTo(0);
|
|
Assert.IsTrue(a.FitsUlong());
|
|
a.Value = a - 1;
|
|
Assert.IsFalse(a.FitsUlong());
|
|
a.Value = a + small;
|
|
Assert.IsTrue(a.FitsUlong());
|
|
}
|
|
}
|
|
|
|
[TestMethod]
|
|
public void FloatFitsLong()
|
|
{
|
|
using (var a = new HugeFloat(long.MaxValue))
|
|
using (var small = new HugeFloat(0.0001))
|
|
{
|
|
Assert.IsTrue(a.FitsLong());
|
|
a.Value = a + 1;
|
|
Assert.IsFalse(a.FitsLong());
|
|
a.Value = a - small;
|
|
Assert.IsTrue(a.FitsLong());
|
|
a.SetTo(long.MinValue);
|
|
Assert.IsTrue(a.FitsLong());
|
|
a.Value = a - 1;
|
|
Assert.IsFalse(a.FitsLong());
|
|
a.Value = a + small;
|
|
Assert.IsTrue(a.FitsLong());
|
|
}
|
|
}
|
|
#endif
|
|
|
|
[TestMethod]
|
|
public void FloatFitsUint()
|
|
{
|
|
using (var a = new HugeFloat(uint.MaxValue))
|
|
using (var small = new HugeFloat(0.0001))
|
|
{
|
|
Assert.IsTrue(a.FitsUint());
|
|
a.Value = a + 1;
|
|
Assert.IsFalse(a.FitsUint());
|
|
a.Value = a - small;
|
|
Assert.IsTrue(a.FitsUint());
|
|
a.SetTo(0);
|
|
Assert.IsTrue(a.FitsUint());
|
|
a.Value = a - 1;
|
|
Assert.IsFalse(a.FitsUint());
|
|
a.Value = a + small;
|
|
Assert.IsTrue(a.FitsUint());
|
|
}
|
|
}
|
|
|
|
[TestMethod]
|
|
public void FloatFitsInt()
|
|
{
|
|
using (var a = new HugeFloat(int.MaxValue))
|
|
using (var small = new HugeFloat(0.0001))
|
|
{
|
|
Assert.IsTrue(a.FitsInt());
|
|
a.Value = a + 1;
|
|
Assert.IsFalse(a.FitsInt());
|
|
a.Value = a - small;
|
|
Assert.IsTrue(a.FitsInt());
|
|
a.SetTo(int.MinValue);
|
|
Assert.IsTrue(a.FitsInt());
|
|
a.Value = a - 1;
|
|
Assert.IsFalse(a.FitsInt());
|
|
a.Value = a + small;
|
|
Assert.IsTrue(a.FitsInt());
|
|
}
|
|
}
|
|
|
|
[TestMethod]
|
|
public void FloatFitsUshort()
|
|
{
|
|
using (var a = new HugeFloat(ushort.MaxValue))
|
|
using (var small = new HugeFloat(0.0001))
|
|
{
|
|
Assert.IsTrue(a.FitsUshort());
|
|
a.Value = a + 1;
|
|
Assert.IsFalse(a.FitsUshort());
|
|
a.Value = a - small;
|
|
Assert.IsTrue(a.FitsUshort());
|
|
a.SetTo(0);
|
|
Assert.IsTrue(a.FitsUshort());
|
|
a.Value = a - 1;
|
|
Assert.IsFalse(a.FitsUshort());
|
|
a.Value = a + small;
|
|
Assert.IsTrue(a.FitsUshort());
|
|
}
|
|
}
|
|
|
|
[TestMethod]
|
|
public void FloatFitsShort()
|
|
{
|
|
using (var a = new HugeFloat(short.MaxValue))
|
|
using (var small = new HugeFloat(0.0001))
|
|
{
|
|
Assert.IsTrue(a.FitsShort());
|
|
a.Value = a + 1;
|
|
Assert.IsFalse(a.FitsShort());
|
|
a.Value = a - small;
|
|
Assert.IsTrue(a.FitsShort());
|
|
a.SetTo(short.MinValue);
|
|
Assert.IsTrue(a.FitsShort());
|
|
a.Value = a - 1;
|
|
Assert.IsFalse(a.FitsShort());
|
|
a.Value = a + small;
|
|
Assert.IsTrue(a.FitsShort());
|
|
}
|
|
}
|
|
|
|
[TestMethod]
|
|
public void FloatIsInteger()
|
|
{
|
|
using (var a = new HugeFloat("-233454059287409285742345.125"))
|
|
{
|
|
Assert.IsFalse(a.IsInteger());
|
|
a.Value = a * 8;
|
|
Assert.IsTrue(a.IsInteger());
|
|
}
|
|
}
|
|
|
|
//private void AssertBetween(int min, int max, long actual)
|
|
//{
|
|
// Assert.IsTrue(actual >= min && actual <= max, "Expected {0} to {1}, actual {2}", min, max, actual);
|
|
//}
|
|
}
|
|
}
|