context: /*
  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 = 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 = 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);
  
gt:                 Assert.AreEqual("0." + n + "@" + n.Length, a.ToString(10));