Пример #1
0
        public void TestSubnormal()
        {
            ExpandedDouble hd = new ExpandedDouble(0x0000000000000001L);

            if (hd.GetBinaryExponent() == -1023)
            {
                throw new AssertionException("identified bug - subnormal numbers not decoded properly");
            }
            Assert.AreEqual(-1086, hd.GetBinaryExponent());
            BigInteger frac = hd.GetSignificand();
            Assert.AreEqual(64, frac.BitLength());
            Assert.AreEqual(1, frac.BitCount());
        }
Пример #2
0
        public void TestNegative()
        {
            ExpandedDouble hd = new ExpandedDouble(unchecked((long)0xC010000000000000L));

            if (hd.GetBinaryExponent() == -2046)
            {
                throw new AssertionException("identified bug - sign bit not masked out of exponent");
            }
            Assert.AreEqual(2, hd.GetBinaryExponent());
            BigInteger frac = hd.GetSignificand();
            Assert.AreEqual(64, frac.BitLength());
            Assert.AreEqual(1, frac.BitCount());
        }
Пример #3
0
        public static bool ConfirmRoundTrip(int i, long rawBitsA)
        {
            double a = BitConverter.Int64BitsToDouble(rawBitsA);
            if (a == 0.0)
            {
                // Can't represent 0.0 or -0.0 with NormalisedDecimal
                return true;
            }
            ExpandedDouble ed1;
            NormalisedDecimal nd2;
            ExpandedDouble ed3;
            try
            {
                ed1 = new ExpandedDouble(rawBitsA);
                nd2 = ed1.NormaliseBaseTen();
                CheckNormaliseBaseTenResult(ed1, nd2);

                ed3 = nd2.NormaliseBaseTwo();
            }
            catch (Exception e)
            {
                Console.WriteLine("example[" + i + "] ("
                        + FormatDoubleAsHex(a) + ") exception: " + e.Message);
                return false;
            }
            if (ed3.GetBinaryExponent() != ed1.GetBinaryExponent())
            {
                Console.WriteLine("example[" + i + "] ("
                        + FormatDoubleAsHex(a) + ") bin exp mismatch");
                return false;
            }
            BigInteger diff = ed3.GetSignificand() - (ed1.GetSignificand()).Abs();
            if (diff.Signum() == 0)
            {
                return true;
            }
            // original quantity only has 53 bits of precision
            // these quantities may have errors in the 64th bit, which hopefully don't make any difference

            if (diff.BitCount() < 2)
            {
                // errors in the 64th bit happen from time to time
                // this is well below the 53 bits of precision required
                return true;
            }

            // but bigger errors are a concern
            Console.WriteLine("example[" + i + "] ("
                    + FormatDoubleAsHex(a) + ") frac mismatch: " + diff.ToString());

            for (int j = -2; j < 3; j++)
            {
                Console.WriteLine((j < 0 ? "" : "+") + j + ": " + GetNearby(ed1, j));
            }
            for (int j = -2; j < 3; j++)
            {
                Console.WriteLine((j < 0 ? "" : "+") + j + ": " + GetNearby(nd2, j));
            }

            return false;
        }
Пример #4
0
        private static void CheckNormaliseBaseTenResult(ExpandedDouble orig, NormalisedDecimal result)
        {
            String sigDigs = result.GetSignificantDecimalDigits();
            BigInteger frac = orig.GetSignificand();
            while (frac.BitLength() + orig.GetBinaryExponent() < 200)
            {
                frac = frac * (BIG_POW_10);
            }
            int binaryExp = orig.GetBinaryExponent() - orig.GetSignificand().BitLength();

            String origDigs = (frac << (binaryExp + 1)).ToString(10);

            if (!origDigs.StartsWith(sigDigs))
            {
                throw new AssertionException("Expected '" + origDigs + "' but got '" + sigDigs + "'.");
            }

            double dO = Double.Parse("0." + origDigs.Substring(sigDigs.Length));
            double d1 = Double.Parse(result.GetFractionalPart().ToString());
            BigInteger subDigsO = new BigInteger((int)(dO * 32768 + 0.5));
            BigInteger subDigsB = new BigInteger((int)(d1 * 32768 + 0.5));

            if (subDigsO.Equals(subDigsB))
            {
                return;
            }
            BigInteger diff = (subDigsB - subDigsO).Abs();
            if (diff.IntValue() > 100)
            {
                // 100/32768 ~= 0.003
                throw new AssertionException("minor mistake");
            }
        }
Пример #5
0
 public static BigInteger GetNearby(ExpandedDouble hd, int offset)
 {
     return GetNearby(hd.GetSignificand(), hd.GetBinaryExponent(), offset);
 }