예제 #1
0
        public void Modulus()
        {
            for (int i = sbyte.MinValue; i <= sbyte.MaxValue; ++i)
            {
                var f1 = Fix8.FromRaw((sbyte)i);
                for (int j = sbyte.MinValue; j <= sbyte.MaxValue; ++j)
                {
                    var f2 = Fix8.FromRaw((sbyte)j);

                    if (j == 0)
                    {
                        Assert.Throws <DivideByZeroException>(() => Ignore(f1 % f2));
                    }
                    else
                    {
                        var d1       = (decimal)f1;
                        var d2       = (decimal)f2;
                        var expected = d1 % d2;
                        var actual   = (decimal)(f1 % f2);
                        //var delta = Math.Abs(expected - actual);
                        Assert.Equal(expected, actual);
                        //Assert.LessOrEqual(delta, Fix8.Precision, string.Format("{0} % {1} = expected {2} but got {3}", f1, f2, expected, actual));
                    }
                }
            }
        }
예제 #2
0
 public void Subtraction()
 {
     // Testing every possible combination of terms
     // now that's what I call coverage
     //var sw = new Stopwatch();
     //for (var k = 0; k < 100; ++k) {
     for (int i = sbyte.MinValue; i <= sbyte.MaxValue; ++i)
     {
         for (int j = sbyte.MinValue; j <= sbyte.MaxValue; ++j)
         {
             var op1      = Fix8.FromRaw((sbyte)i);
             var op2      = Fix8.FromRaw((sbyte)j);
             var expected = (decimal)op1 - (decimal)op2;
             expected =
                 expected > (decimal)Fix8.MaxValue
                     ? (decimal)Fix8.MaxValue
                     : expected < (decimal)Fix8.MinValue
                           ? (decimal)Fix8.MinValue
                           : expected;
             //sw.Start();
             var actual = op1 - op2;
             //sw.Stop();
             var actualM = (decimal)actual;
             if (expected != actualM)
             {
                 Console.WriteLine("Failed for {0} - {1}: expected {2} but got {3}", op1, op2, expected, actual);
             }
             Assert.Equal(expected, actualM);
         }
     }
     //}
     //Console.WriteLine("Fix8: {0} total, {1} per substraction", sw.ElapsedMilliseconds, sw.Elapsed.Milliseconds / (100 * 65536.0));
 }
예제 #3
0
 public void Floor()
 {
     for (int i = sbyte.MinValue; i <= sbyte.MaxValue; ++i)
     {
         var f        = Fix8.FromRaw((sbyte)i);
         var expected = Math.Floor((decimal)f);
         var actual   = (decimal)Fix8.Floor(f);
         Assert.Equal(expected, actual);
     }
 }
예제 #4
0
 public void Abs()
 {
     Assert.Equal(Fix8.MaxValue, Fix8.Abs(Fix8.MinValue));
     for (int i = sbyte.MinValue + 1; i <= sbyte.MaxValue; ++i)
     {
         var f        = Fix8.FromRaw((sbyte)i);
         var original = (decimal)f;
         var expected = Math.Abs(original);
         var actual   = (decimal)(Fix8.Abs(f));
         Assert.Equal(expected, actual);
     }
 }
예제 #5
0
 public void Round()
 {
     for (int i = sbyte.MinValue; i <= sbyte.MaxValue; ++i)
     {
         var f        = Fix8.FromRaw((sbyte)i);
         var expected = Math.Round((decimal)f);
         expected =
             expected > (decimal)Fix8.MaxValue ? (decimal)Fix8.MaxValue :
             expected < (decimal)Fix8.MinValue ? (decimal)Fix8.MinValue
                      : expected;
         var actual = (decimal)Fix8.Round(f);
         Assert.Equal(expected, actual);
     }
 }
예제 #6
0
 public void Sqrt()
 {
     for (int i = sbyte.MinValue; i <= sbyte.MaxValue; ++i)
     {
         var f = Fix8.FromRaw((sbyte)i);
         if (i < 0)
         {
             Assert.Throws <ArgumentOutOfRangeException>(() => Fix8.Sqrt(f));
         }
         else
         {
             var expected = (decimal)Math.Sqrt((double)(decimal)f);
             var actual   = (decimal)Fix8.Sqrt(f);
             var delta    = Math.Abs(expected - actual);
             Assert.True(delta <= 0.0625m / 2m);
         }
     }
 }
예제 #7
0
        public void Multiplication()
        {
            int failed = 0;
            var sw     = new Stopwatch();
            var swf    = new Stopwatch();
            var swd    = new Stopwatch();

            //for (int k = 0; k < 100; ++k) {
            for (int i = sbyte.MinValue; i <= sbyte.MaxValue; ++i)
            {
                var op1 = Fix8.FromRaw((sbyte)i);

                for (int j = sbyte.MinValue; j <= sbyte.MaxValue; ++j)
                {
                    var op2 = Fix8.FromRaw((sbyte)j);

                    var op1d = (double)(decimal)op1;
                    var op2d = (double)(decimal)op2;
                    swd.Start();
                    var resultd = op1d * op2d;
                    swd.Stop();

                    var op1f = (float)(decimal)op1;
                    var op2f = (float)(decimal)op2;
                    swf.Start();
                    var resultf = op1f * op2f;
                    swf.Stop();

                    sw.Start();
                    var actualF = op1 * op2;
                    sw.Stop();
                    var actual   = (decimal)(actualF);
                    var expected = (decimal)op1 * (decimal)op2;
                    expected =
                        expected > (decimal)Fix8.MaxValue
                            ? (decimal)Fix8.MaxValue
                            : expected < (decimal)Fix8.MinValue
                                  ? (decimal)Fix8.MinValue
                                  : expected;
                    var expectedRounded = Math.Round(expected * 16m) * 0.0625m;
                    var delta           = Math.Abs(expected - actual);

                    // Fix8 correctly rounds within half of its precision, but doesn't use the banker's algorithm
                    // like Math.Round().
                    if (delta > (0.0625m / 2.0m))
                    {
                        Console.WriteLine("Failed {0} * {1} : expected {2} but got {3}", op1, op2, expectedRounded, actual);
                        ++failed;
                    }

                    if (double.IsNaN(resultd) || float.IsNaN(resultf))
                    {
                        Console.WriteLine("");
                    }
                    //Assert.Equal(expected, actual);
                }
            }
            //}
            //Console.WriteLine("Fix8: {0} total, {1} per multiplication", sw.ElapsedMilliseconds, sw.Elapsed.Milliseconds / (100*65536.0));
            //Console.WriteLine("Double: {0} total, {1} per multiplication", swd.ElapsedMilliseconds, swd.Elapsed.Milliseconds / (100*65536.0));
            //Console.WriteLine("Float: {0} total, {1} per multiplication", swf.ElapsedMilliseconds, swf.Elapsed.Milliseconds / (100*65536.0));
            Assert.Equal(0, failed);
        }
예제 #8
0
        public void Division()
        {
            int failed = 0;

            //var sw = new Stopwatch();
            //var swf = new Stopwatch();
            //var swd = new Stopwatch();
            //for (int k = 0; k < 100; ++k) {
            for (int i = sbyte.MinValue; i <= sbyte.MaxValue; ++i)
            {
                var op1 = Fix8.FromRaw((sbyte)i);
                for (int j = sbyte.MinValue; j <= sbyte.MaxValue; ++j)
                {
                    var op2 = Fix8.FromRaw((sbyte)j);
                    if (j == 0)
                    {
                        Assert.Throws <DivideByZeroException>(() => Ignore(op1 / op2));
                    }
                    else
                    {
                        //var op1d = (double)(decimal)op1;
                        //var op2d = (double)(decimal)op2;
                        //swd.Start();
                        //var resultd = op1d / op2d;
                        //swd.Stop();

                        //var op1f = (float)(decimal)op1;
                        //var op2f = (float)(decimal)op2;
                        //swf.Start();
                        //var resultf = op1f / op2f;
                        //swf.Stop();

                        //sw.Start();
                        var actualF = op1 / op2;
                        //sw.Stop();
                        var actual   = (decimal)(actualF);
                        var expected = (decimal)op1 / (decimal)op2;
                        expected =
                            expected > (decimal)Fix8.MaxValue
                                    ? (decimal)Fix8.MaxValue
                                    : expected < (decimal)Fix8.MinValue
                                          ? (decimal)Fix8.MinValue
                                          : expected;
                        var expectedRounded = Math.Round(expected * 16m) * 0.0625m;
                        var delta           = Math.Abs(expected - actual);
                        if (delta > (0.0625m / 2m))
                        {
                            Console.WriteLine("Failed {0} / {1} : expected {2} but got {3}", op1, op2, expectedRounded, actual);
                            ++failed;
                        }

                        // This is just to prevent the optimizer from removing the double and float operations
                        //if (double.IsNaN(resultd) || float.IsNaN(resultf)) {
                        //    Console.WriteLine("");
                        //}
                    }
                }
            }

            //}
            //Console.WriteLine("Fix8: {0} total, {1} per division", sw.ElapsedMilliseconds, sw.Elapsed.Milliseconds / (100 * 65536.0));
            //Console.WriteLine("Double: {0} total, {1} per division", swd.ElapsedMilliseconds, swd.Elapsed.Milliseconds / (100 * 65536.0));
            //Console.WriteLine("Float: {0} total, {1} per division", swf.ElapsedMilliseconds, swf.Elapsed.Milliseconds / (100 * 65536.0));
            Assert.Equal(0, failed);
        }