diff --git a/Tests/MathUnitTests/MathUnitTest.cs b/Tests/MathUnitTests/MathUnitTest.cs index e05b594..e50f12a 100644 --- a/Tests/MathUnitTests/MathUnitTest.cs +++ b/Tests/MathUnitTests/MathUnitTest.cs @@ -148,20 +148,20 @@ public static void Clamp_Float() [TestMethod] public static void Clamp_MinGreaterThanMax_ThrowsArgumentException() { - Assert.Throws(typeof(ArgumentException), () => Math.Clamp((sbyte)1, (sbyte)2, (sbyte)1)); - Assert.Throws(typeof(ArgumentException), () => Math.Clamp((byte)1, (byte)2, (byte)1)); - Assert.Throws(typeof(ArgumentException), () => Math.Clamp((short)1, (short)2, (short)1)); - Assert.Throws(typeof(ArgumentException), () => Math.Clamp((ushort)1, (ushort)2, (ushort)1)); + Assert.ThrowsException(typeof(ArgumentException), () => Math.Clamp((sbyte)1, (sbyte)2, (sbyte)1)); + Assert.ThrowsException(typeof(ArgumentException), () => Math.Clamp((byte)1, (byte)2, (byte)1)); + Assert.ThrowsException(typeof(ArgumentException), () => Math.Clamp((short)1, (short)2, (short)1)); + Assert.ThrowsException(typeof(ArgumentException), () => Math.Clamp((ushort)1, (ushort)2, (ushort)1)); // keeping cast on purpose to be able to test the method #pragma warning disable IDE0004 #pragma warning disable S1905 - Assert.Throws(typeof(ArgumentException), () => Math.Clamp((int)1, (int)2, (int)1)); - Assert.Throws(typeof(ArgumentException), () => Math.Clamp((uint)1, (uint)2, (uint)1)); - Assert.Throws(typeof(ArgumentException), () => Math.Clamp((long)1, (long)2, (long)1)); - Assert.Throws(typeof(ArgumentException), () => Math.Clamp((ulong)1, (ulong)2, (ulong)1)); - Assert.Throws(typeof(ArgumentException), () => Math.Clamp((float)1, (float)2, (float)1)); - Assert.Throws(typeof(ArgumentException), () => Math.Clamp((double)1, (double)2, (double)1)); + Assert.ThrowsException(typeof(ArgumentException), () => Math.Clamp((int)1, (int)2, (int)1)); + Assert.ThrowsException(typeof(ArgumentException), () => Math.Clamp((uint)1, (uint)2, (uint)1)); + Assert.ThrowsException(typeof(ArgumentException), () => Math.Clamp((long)1, (long)2, (long)1)); + Assert.ThrowsException(typeof(ArgumentException), () => Math.Clamp((ulong)1, (ulong)2, (ulong)1)); + Assert.ThrowsException(typeof(ArgumentException), () => Math.Clamp((float)1, (float)2, (float)1)); + Assert.ThrowsException(typeof(ArgumentException), () => Math.Clamp((double)1, (double)2, (double)1)); #pragma warning restore S1905 #pragma warning restore IDE0004 } @@ -201,6 +201,7 @@ public static void Test_Not_Numbers() double pos_inf = (3.0 / 0.0); double neg_inf = (-3.0 / 0.0); + Console.WriteLine($"Expect nan={nan}, pos_inf={pos_inf}, neg_inf={neg_inf}"); Assert.IsTrue(double.IsNaN(nan), "NaN was not correctly identified"); Assert.IsFalse(double.IsPositiveInfinity(nan), "NaN was incorrectly identified as Positive Infinity"); @@ -208,15 +209,15 @@ public static void Test_Not_Numbers() //--// + Assert.IsFalse(double.IsNaN(pos_inf), "Positive Infinity was incorrectly identified as double.NaN"); Assert.IsTrue(double.IsPositiveInfinity(pos_inf), "Positive Infinity was not correctly identified"); - Assert.IsFalse(double.IsNaN(pos_inf), "Positive Infinity was incorrectly identified asdouble.NaN"); Assert.IsFalse(double.IsNegativeInfinity(pos_inf), "Positive Infinity was incorrectly identified as Negative Infinity"); //--// - Assert.IsTrue(double.IsNegativeInfinity(neg_inf), "NegativeInfinity was not correctly identified"); + Assert.IsFalse(double.IsNaN(neg_inf), "NegativeInfinity Infinity was incorrectly identified as double.NaN"); Assert.IsFalse(double.IsPositiveInfinity(neg_inf), "NegativeInfinity Infinity was incorrectly identified as Positive Infinity"); - Assert.IsFalse(double.IsNaN(neg_inf), "NegativeInfinity Infinity was incorrectly identified asdouble.NaN"); + Assert.IsTrue(double.IsNegativeInfinity(neg_inf), "NegativeInfinity was not correctly identified"); } [TestMethod] @@ -665,86 +666,6 @@ public static void Test_Log10() Assert.IsTrue(double.IsNaN(res), $"Log10(...NegativeInfinity) -- FAILED AT: {res}"); } - [TestMethod] - public static void Test_Max_2() - { - // - // Summary: - // Returns the larger of two double-precision floating-point numbers. - // - // Parameters: - // val1: - // The first of two double-precision floating-point numbers to compare. - // - // val2: - // The second of two double-precision floating-point numbers to compare. - // - // Returns: - // Parameter val1 or val2, whichever is larger. If val1 OR both val1 - // and val2 are equal to System.Double.NaN, System.Double.NaN is returned. - double[] x = new double[] { 6.00000000000000000000, 6.50000000000000000000, 7.00000000000000000000, 7.50000000000000000000, -0.50000000000000000000, -1.00000000000000000000, -1.50000000000000000000, -2.00000000000000000000 }; - double[] y = new double[] { 1, 1.140238321, 1.600286858, 2.509178479, 4.121836054, 6.890572365, 11.59195328, -0.50000000000000000000 }; - - double[] answer = new double[] { 6.00000000000000000000, 6.50000000000000000000, 7.00000000000000000000, 7.50000000000000000000, 4.12183605386995000000, 6.89057236497588000000, 11.59195328, -0.50000000000000000000 }; - double res; - - for (int i = 0; i < x.Length; i++) - { - res = Math.Max(x[i], y[i]); - - Assert.IsFalse((answer[i] - res) > 0.0001d || (answer[i] - res) < -0.0001d, $"Max(...{x[i]}, {y[i]}) -- FAILED AT: {res}"); - } - - res = Math.Max(10, double.NaN); - Assert.IsTrue(double.IsNaN(res), $"Max(...10,double.NaN) -- FAILED AT: {res}"); - - res = Math.Max(double.NaN, 10); - Assert.IsTrue(double.IsNaN(res), $"Max(...NaN, 10) -- FAILED AT: {res}"); - - res = Math.Max(double.NaN, double.NaN); - Assert.IsTrue(double.IsNaN(res), $"Max(...NaN,double.NaN) -- FAILED AT: {res}"); - } - - [TestMethod] - public static void Test_Min_2() - { - // - // Summary: - // Returns the smaller of two double-precision floating-point numbers. - // - // Parameters: - // val1: - // The first of two double-precision floating-point numbers to compare. - // - // val2: - // The second of two double-precision floating-point numbers to compare. - // - // Returns: - // Parameter val1 or val2, whichever is smaller. If val1, val2, or both val1 - // and val2 are equal to System.Double.NaN, System.Double.NaN is returned. - double[] x = new double[] { 6.00000000000000000000, 6.50000000000000000000, 7.00000000000000000000, 7.50000000000000000000, -0.50000000000000000000, -1.00000000000000000000, -1.50000000000000000000, -2.00000000000000000000 }; - double[] y = new double[] { 1, 1.140238321, 1.600286858, 2.509178479, 4.121836054, 6.890572365, 11.59195328, -0.50000000000000000000 }; - - double[] answer = new double[] { 1, 1.140238321, 1.600286858, 2.509178479, -0.50000000000000000000, -1.00000000000000000000, -1.50000000000000000000, -2.00000000000000000000 }; - double res; - - for (int i = 0; i < x.Length; i++) - { - res = Math.Min(x[i], y[i]); - - Assert.IsFalse((answer[i] - res) > 0.0001d || (answer[i] - res) < -0.0001d, $"Min(...{x[i]}, {y[i]}) -- FAILED AT: {res}"); - } - - res = Math.Min(10, double.NaN); - Assert.IsTrue(double.IsNaN(res), $"Min(...10,double.NaN) -- FAILED AT: {res}"); - - res = Math.Min(double.NaN, 10); - Assert.AreEqual(res, 10, $"Min(...NaN, 10) -- FAILED AT: {res}"); - - res = Math.Min(double.NaN, double.NaN); - Assert.IsTrue(double.IsNaN(res), $"Min(...NaN,double.NaN) -- FAILED AT: {res}"); - } - [TestMethod] public static void Test_Pow_2() { diff --git a/Tests/MathUnitTests/MathUnitTests.nfproj b/Tests/MathUnitTests/MathUnitTests.nfproj index 2e7ba19..2bdec42 100644 --- a/Tests/MathUnitTests/MathUnitTests.nfproj +++ b/Tests/MathUnitTests/MathUnitTests.nfproj @@ -27,23 +27,26 @@ + + - + + + + ..\..\packages\nanoFramework.CoreLibrary.1.14.2\lib\mscorlib.dll - True - + ..\..\packages\nanoFramework.TestFramework.2.1.85\lib\nanoFramework.TestFramework.dll - True - + ..\..\packages\nanoFramework.TestFramework.2.1.85\lib\nanoFramework.UnitTestLauncher.exe - True + diff --git a/Tests/MathUnitTests/Max_Tests.cs b/Tests/MathUnitTests/Max_Tests.cs new file mode 100644 index 0000000..238134f --- /dev/null +++ b/Tests/MathUnitTests/Max_Tests.cs @@ -0,0 +1,157 @@ +using System; +using nanoFramework.TestFramework; + +namespace MathUnitTests +{ + [TestClass] + public class Max_Tests + { + [TestMethod] + public void Max_Double_returns_greater_value() + { + var val1 = new[] + { + 6.00000000000000000000d, 6.50000000000000000000d, 7.00000000000000000000d, 7.50000000000000000000d, + -0.50000000000000000000d, -1.00000000000000000000d, -1.50000000000000000000d, -2.00000000000000000000d + }; + var val2 = new[] + { + 1d, 1.140238321d, 1.600286858d, 2.509178479d, 4.121836054d, 6.890572365d, 11.59195328d, -0.50000000000000000000d + }; + + var expected = new[] + { + val1[0], val1[1], val1[2], val1[3], val2[4], val2[5], val2[6], val2[7] + }; + + for (var i = 0; i < val1.Length; i++) + { + var actual = Math.Max(val1[i], val2[i]); + + Assert.IsFalse((expected[i] - actual) > 0.0001d || (expected[i] - actual) < -0.0001d); + } + } + + [TestMethod] + public void Max_Double_returns_NaN_if_both_val1_and_val2_are_NaN() + { + var actual = Math.Max(double.NaN, double.NaN); + + Assert.IsTrue(double.IsNaN(actual)); + } + + [TestMethod] + public void Max_Double_returns_NaN_if_val1_is_NaN() + { + var actual = Math.Max(double.NaN, Math.PI); + + Assert.IsTrue(double.IsNaN(actual)); + } + + [TestMethod] + public void Max_Double_returns_NaN_if_val2_is_NaN() + { + var actual = Math.Max(Math.PI, double.NaN); + + Assert.IsTrue(double.IsNaN(actual)); + } + + [TestMethod] + public void Max_Double_treats_positive_zero_as_greater_than_negative_zero() + { + // 00-00-00-00-00-00-00-00 + var positiveZero = 0.0d; + + // 00-00-00-00-00-00-00-80 + var negativeZero = -0.0d; + + var result1 = Math.Max(positiveZero, negativeZero); + var result2 = Math.Max(negativeZero, positiveZero); + + Console.WriteLine(BitConverter.ToString(BitConverter.GetBytes(result1))); + Console.WriteLine(BitConverter.ToString(BitConverter.GetBytes(result2))); + + Assert.AreEqual(positiveZero, result1); + Assert.AreEqual(positiveZero, result2); + } + + [TestMethod] + public void Max_Float_returns_greater_value() + { + var val1 = new[] + { + 6.00000000000000000000f, 6.50000000000000000000f, 7.00000000000000000000f, 7.50000000000000000000f, + -0.50000000000000000000f, -1.00000000000000000000f, -1.50000000000000000000f, -2.00000000000000000000f + }; + var val2 = new[] + { + 1f, 1.140238321f, 1.600286858f, 2.509178479f, 4.121836054f, 6.890572365f, 11.59195328f, -0.50000000000000000000f + }; + + var expected = new[] + { + val1[0], val1[1], val1[2], val1[3], val2[4], val2[5], val2[6], val2[7] + }; + + for (var i = 0; i < val1.Length; i++) + { + var actual = Math.Max(val1[i], val2[i]); + + Assert.AreEqual(expected[i], actual); + } + } + + [TestMethod] + public void Max_Float_returns_NaN_if_both_val1_and_val2_are_NaN() + { + var actual = Math.Max(float.NaN, float.NaN); + + Assert.IsTrue(float.IsNaN(actual)); + } + + [TestMethod] + public void Max_Float_returns_NaN_if_val1_is_NaN() + { + var actual = Math.Max(float.NaN, (float)Math.PI); + + Assert.IsTrue(float.IsNaN(actual)); + } + + [TestMethod] + public void Max_Float_returns_NaN_if_val2_is_NaN() + { + var actual = Math.Max((float)Math.PI, float.NaN); + + Assert.IsTrue(float.IsNaN(actual)); + } + + [TestMethod] + public void Max_Float_treats_positive_zero_as_greater_than_negative_zero() + { + // 00-00-00-00-00-00-00-00 + var positiveZero = 0.0f; + + // 00-00-00-00-00-00-00-80 + var negativeZero = -0.0f; + + var result1 = Math.Max(positiveZero, negativeZero); + var result2 = Math.Max(negativeZero, positiveZero); + + Console.WriteLine(BitConverter.ToString(BitConverter.GetBytes(result1))); + Console.WriteLine(BitConverter.ToString(BitConverter.GetBytes(result2))); + + Assert.AreEqual(positiveZero, result1); + Assert.AreEqual(positiveZero, result2); + } + + [TestMethod] + public void Max_Int_returns_greater_value() + { + var expect = 12345678; + var lower = expect / 2; + + Assert.AreEqual(expect, Math.Max(expect, lower)); + Assert.AreEqual(expect, Math.Max(lower, expect)); + } + } +} diff --git a/Tests/MathUnitTests/Min_Tests.cs b/Tests/MathUnitTests/Min_Tests.cs new file mode 100644 index 0000000..cf59030 --- /dev/null +++ b/Tests/MathUnitTests/Min_Tests.cs @@ -0,0 +1,161 @@ +using System; +using nanoFramework.TestFramework; + +namespace MathUnitTests +{ + [TestClass] + public class Min_Tests + { + [TestMethod] + public void Min_Double_returns_lesser_value() + { + var val1 = new[] + { + 6.00000000000000000000d, 6.50000000000000000000d, 7.00000000000000000000d, 7.50000000000000000000d, + -0.50000000000000000000d, -1.00000000000000000000d, -1.50000000000000000000d, -2.00000000000000000000d + }; + var val2 = new[] + { + 1d, 1.140238321d, 1.600286858d, 2.509178479d, 4.121836054d, 6.890572365d, 11.59195328d, -0.50000000000000000000d + }; + + var expected = new[] + { + val2[0], val2[1], val2[2], val2[3], val1[4], val1[5], val1[6], val1[7] + }; + + for (var i = 0; i < val1.Length; i++) + { + var actual = Math.Min(val1[i], val2[i]); + + Assert.IsFalse((expected[i] - actual) > 0.0001d || (expected[i] - actual) < -0.0001d); + } + } + + [TestMethod] + public void Min_Double_returns_NaN_if_both_val1_and_val2_are_NaN() + { + var actual = Math.Min(double.NaN, double.NaN); + + Assert.IsTrue(double.IsNaN(actual)); + } + + [TestMethod] + public void Min_Double_returns_NaN_if_val1_is_NaN() + { + var actual = Math.Min(double.NaN, Math.PI); + + Assert.IsTrue(double.IsNaN(actual)); + } + + [TestMethod] + public void Min_Double_returns_NaN_if_val2_is_NaN() + { + var actual = Math.Min(Math.PI, double.NaN); + + Assert.IsTrue(double.IsNaN(actual)); + } + + [TestMethod] + public void Min_Double_treats_positive_zero_as_lesser_than_negative_zero() + { + // TODO: Not sure what is going on with this test but so far compliance in 3 out of 4 cases is better than where we were before :shrug: + // 00-00-00-00-00-00-00-00 + var positiveZero = 0.0d; + + // 00-00-00-00-00-00-00-80 + var negativeZero = -0.0d; + + var result1 = Math.Min(positiveZero, negativeZero); + var result2 = Math.Min(negativeZero, positiveZero); + + Console.WriteLine(BitConverter.ToString(BitConverter.GetBytes(result1))); + Console.WriteLine(BitConverter.ToString(BitConverter.GetBytes(result2))); + + Assert.AreEqual(positiveZero, result1); + Assert.AreEqual(positiveZero, result2); + } + + [TestMethod] + public void Min_Float_returns_lesser_value() + { + var val1 = new[] + { + 6.00000000000000000000f, 6.50000000000000000000f, 7.00000000000000000000f, 7.50000000000000000000f, + -0.50000000000000000000f, -1.00000000000000000000f, -1.50000000000000000000f, -2.00000000000000000000f + }; + var val2 = new[] + { + 1f, 1.140238321f, 1.600286858f, 2.509178479f, 4.121836054f, 6.890572365f, 11.59195328f, -0.50000000000000000000f + }; + + var expected = new[] + { + val2[0], val2[1], val2[2], val2[3], val1[4], val1[5], val1[6], val1[7] + }; + + for (var i = 0; i < val1.Length; i++) + { + var actual = Math.Min(val1[i], val2[i]); + + Assert.AreEqual(expected[i], actual); + } + } + + [TestMethod] + public void Min_Float_returns_NaN_if_both_val1_and_val2_are_NaN() + { + var actual = Math.Min(float.NaN, float.NaN); + + Assert.IsTrue(float.IsNaN(actual)); + } + + [TestMethod] + public void Min_Float_returns_NaN_if_val1_is_NaN() + { + var actual = Math.Min(float.NaN, (float) Math.PI); + + Assert.IsTrue(float.IsNaN(actual)); + } + + [TestMethod] + public void Min_Float_returns_NaN_if_val2_is_NaN() + { + var actual = Math.Min((float) Math.PI, float.NaN); + + Assert.IsTrue(float.IsNaN(actual)); + } + + [TestMethod] + public void Min_Float_treats_positive_zero_as_lesser_than_negative_zero() + { + // 00-00-00-00 + var positiveZero = 0.0f; + + // 00-00-00-80 + var negativeZero = -0.0f; + + Console.WriteLine(BitConverter.ToString(BitConverter.GetBytes(positiveZero))); + Console.WriteLine(BitConverter.ToString(BitConverter.GetBytes(negativeZero))); + + var result1 = Math.Min(positiveZero, negativeZero); + var result2 = Math.Min(negativeZero, positiveZero); + + Console.WriteLine(BitConverter.ToString(BitConverter.GetBytes(result1))); + Console.WriteLine(BitConverter.ToString(BitConverter.GetBytes(result2))); + + Assert.AreEqual(positiveZero, result1); + Assert.AreEqual(positiveZero, result2); + } + + [TestMethod] + public void Min_Int_returns_lesser_value() + { + var expect = 12345678; + var higher = expect * 2; + + Assert.AreEqual(expect, Math.Min(expect, higher)); + Assert.AreEqual(expect, Math.Min(higher, expect)); + } + } +} diff --git a/Tests/MathUnitTests/nano.runsettings b/Tests/MathUnitTests/nano.runsettings new file mode 100644 index 0000000..93ce85e --- /dev/null +++ b/Tests/MathUnitTests/nano.runsettings @@ -0,0 +1,17 @@ + + + + + .\TestResults + 120000 + net48 + x64 + + + None + False + COM3 + + + + \ No newline at end of file diff --git a/nanoFramework.System.Math.Benchmark/BenchmarksBase.cs b/nanoFramework.System.Math.Benchmark/BenchmarksBase.cs new file mode 100644 index 0000000..ea6b2b9 --- /dev/null +++ b/nanoFramework.System.Math.Benchmark/BenchmarksBase.cs @@ -0,0 +1,18 @@ +using System; + +namespace MathBenchmarks +{ + public abstract class BenchmarksBase + { + protected const int Iterations = 250; + protected const int Loops = 100; + + public void RunIterations(int iterations, Action action) + { + for (var i = 0; i < iterations; i++) + { + action(); + } + } + } +} diff --git a/nanoFramework.System.Math.Benchmark/IAssemblyHandler.cs b/nanoFramework.System.Math.Benchmark/IAssemblyHandler.cs index e7ddbc6..07ccd5e 100644 --- a/nanoFramework.System.Math.Benchmark/IAssemblyHandler.cs +++ b/nanoFramework.System.Math.Benchmark/IAssemblyHandler.cs @@ -1,4 +1,4 @@ -namespace nanoFramework.System.Math.Benchmark +namespace MathBenchmarks { public interface IAssemblyHandler { diff --git a/nanoFramework.System.Math.Benchmark/MathBenchmark.cs b/nanoFramework.System.Math.Benchmark/MathBenchmark.cs index 723a114..d885a76 100644 --- a/nanoFramework.System.Math.Benchmark/MathBenchmark.cs +++ b/nanoFramework.System.Math.Benchmark/MathBenchmark.cs @@ -1,9 +1,9 @@ -extern alias Core; +using System; +using System.Diagnostics; using nanoFramework.Benchmark; using nanoFramework.Benchmark.Attributes; -using System.Diagnostics; -namespace nanoFramework.System.Math.Benchmark +namespace MathBenchmarks { [DebugLogger] [ConsoleParser] @@ -18,182 +18,152 @@ public MathBenchmark() [Benchmark] public void Math_Abs_int() { - var test = Core.System.Math.Abs(-15); + var test = Math.Abs(-15); } [Benchmark] public void Math_Abs_float() { - var test = Core.System.Math.Abs(-15f); + var test = Math.Abs(-15f); } [Benchmark] public void Math_Abs_double() { - var test = Core.System.Math.Abs(-15d); + var test = Math.Abs(-15d); } [Benchmark] public void Math_Acos() { - var test = Core.System.Math.Acos(-15); + var test = Math.Acos(-15); } [Benchmark] public void Math_Asin() { - var test = Core.System.Math.Asin(-15); + var test = Math.Asin(-15); } [Benchmark] public void Math_Atan() { - var test = Core.System.Math.Atan(-15); + var test = Math.Atan(-15); } [Benchmark] public void Math_Atan2() { - var test = Core.System.Math.Atan2(-15, -15); + var test = Math.Atan2(-15, -15); } [Benchmark] public void Math_Cbrt() { - var test = Core.System.Math.Cbrt(144); + var test = Math.Cbrt(144); } [Benchmark] public void Math_Ceiling() { - var test = Core.System.Math.Ceiling(-15); + var test = Math.Ceiling(-15); } [Benchmark] public void Math_Clamp_double() { - var test = Core.System.Math.Clamp(15d, -15d, 150d); + var test = Math.Clamp(15d, -15d, 150d); } [Benchmark] public void Math_Clamp_long() { - var test = Core.System.Math.Clamp(15L, -15L, 150L); + var test = Math.Clamp(15L, -15L, 150L); } [Benchmark] public void Math_Clamp_long_usigned() { - var test = Core.System.Math.Clamp(15u, -15u, 150u); + var test = Math.Clamp(15u, -15u, 150u); } [Benchmark] public void Math_Clamp_float() { - var test = Core.System.Math.Clamp(15f, -15f, 150f); + var test = Math.Clamp(15f, -15f, 150f); } [Benchmark] public void Math_Cos() { - var test = Core.System.Math.Cos(-15); + var test = Math.Cos(-15); } [Benchmark] public void Math_Cosh() { - var test = Core.System.Math.Cosh(-15); + var test = Math.Cosh(-15); } [Benchmark] public void Math_Exp() { - var test = Core.System.Math.Exp(-15); + var test = Math.Exp(-15); } [Benchmark] public void Math_Floor() { - var test = Core.System.Math.Floor(-15); + var test = Math.Floor(-15); } [Benchmark] public void Math_IEEERemainder() { - var test = Core.System.Math.IEEERemainder(-15, 15); + var test = Math.IEEERemainder(-15, 15); } [Benchmark] public void Math_Log() { - var test = Core.System.Math.Log(-15); + var test = Math.Log(-15); } [Benchmark] public void Math_Log10() { - var test = Core.System.Math.Log10(-15); - } - [Benchmark] - public void Math_Max_int() - { - var test = Core.System.Math.Max(-15, 15); - } - [Benchmark] - public void Math_Max_double() - { - var test = Core.System.Math.Max(-15d, 15d); - } - [Benchmark] - public void Math_Max_float() - { - var test = Core.System.Math.Max(-15f, 15f); - } - [Benchmark] - public void Math_Min_int() - { - var test = Core.System.Math.Min(-15, 15); - } - [Benchmark] - public void Math_Min_double() - { - var test = Core.System.Math.Min(-15d, 15d); - } - [Benchmark] - public void Math_Min_float() - { - var test = Core.System.Math.Min(-15f, 15f); + var test = Math.Log10(-15); } [Benchmark] public void Math_Pow() { - var test = Core.System.Math.Pow(-15, 15); + var test = Math.Pow(-15, 15); } [Benchmark] public void Math_Round() { - var test = Core.System.Math.Round(-15); + var test = Math.Round(-15); } [Benchmark] public void Math_Sign_double() { - var test = Core.System.Math.Sign(-15d); + var test = Math.Sign(-15d); } [Benchmark] public void Math_Sign_float() { - var test = Core.System.Math.Sign(-15f); + var test = Math.Sign(-15f); } [Benchmark] public void Math_Sin() { - var test = Core.System.Math.Sin(-15); + var test = Math.Sin(-15); } [Benchmark] public void Math_Sinh() { - var test = Core.System.Math.Sinh(-15); + var test = Math.Sinh(-15); } [Benchmark] public void Math_Sqrt() { - var test = Core.System.Math.Sqrt(-15); + var test = Math.Sqrt(-15); } [Benchmark] public void Math_Tan() { - var test = Core.System.Math.Tan(-15); + var test = Math.Tan(-15); } [Benchmark] public void Math_Tanh() { - var test = Core.System.Math.Tanh(-15); + var test = Math.Tanh(-15); } [Benchmark] public void Math_Truncate() { - var test = Core.System.Math.Truncate(-15); + var test = Math.Truncate(-15); } } } diff --git a/nanoFramework.System.Math.Benchmark/MaxBenchmarks.cs b/nanoFramework.System.Math.Benchmark/MaxBenchmarks.cs new file mode 100644 index 0000000..2d0ee02 --- /dev/null +++ b/nanoFramework.System.Math.Benchmark/MaxBenchmarks.cs @@ -0,0 +1,55 @@ +using nanoFramework.Benchmark; +using nanoFramework.Benchmark.Attributes; +using System; + +namespace MathBenchmarks +{ + [IterationCount(Iterations)] + public class MaxBenchmarks: BenchmarksBase + { + protected const double DoublePositive1 = Math.PI; + protected const double DoublePositive2 = DoublePositive1 * 2; + protected const double DoubleNegative1 = DoublePositive1 * -1; + + protected const float FloatPositive1 = (float)Math.PI; + protected const float FloatPositive2 = FloatPositive1 * 2; + protected const float FloatNegative1 = FloatPositive1 * -1; + + protected const int IntPositive1 = 123456789; + protected const int IntPositive2 = IntPositive1 * 2; + protected const int IntNegative1 = IntPositive1 * -1; + + [Benchmark] + public void Max_Double() + { + RunIterations(Loops, () => + { + var result1 = Math.Max(DoublePositive1, DoubleNegative1); + var result2 = Math.Max(DoublePositive2, DoublePositive1); + var result3 = Math.Max(double.NaN, DoublePositive2); + }); + } + + [Benchmark] + public void Max_Float() + { + RunIterations(Loops, () => + { + var result1 = Math.Max(FloatPositive1, FloatNegative1); + var result2 = Math.Max(FloatPositive2, FloatPositive1); + var result3 = Math.Max(float.NaN, FloatPositive2); + }); + } + + [Benchmark] + public void Max_Int() + { + RunIterations(Loops, () => + { + var result1 = Math.Max(IntPositive1, IntNegative1); + var result2 = Math.Max(IntPositive2, IntPositive1); + var result3 = Math.Max(IntNegative1, IntPositive2); + }); + } + } +} diff --git a/nanoFramework.System.Math.Benchmark/MinBenchmarks.cs b/nanoFramework.System.Math.Benchmark/MinBenchmarks.cs new file mode 100644 index 0000000..a6ef46e --- /dev/null +++ b/nanoFramework.System.Math.Benchmark/MinBenchmarks.cs @@ -0,0 +1,55 @@ +using nanoFramework.Benchmark; +using nanoFramework.Benchmark.Attributes; +using System; + +namespace MathBenchmarks +{ + [IterationCount(Iterations)] + public class MinBenchmarks: BenchmarksBase + { + protected const double DoublePositive1 = Math.PI; + protected const double DoublePositive2 = DoublePositive1 * 2; + protected const double DoubleNegative1 = DoublePositive1 * -1; + + protected const float FloatPositive1 = (float)Math.PI; + protected const float FloatPositive2 = FloatPositive1 * 2; + protected const float FloatNegative1 = FloatPositive1 * -1; + + protected const int IntPositive1 = 123456789; + protected const int IntPositive2 = IntPositive1 * 2; + protected const int IntNegative1 = IntPositive1 * -1; + + [Benchmark] + public void Min_Double() + { + RunIterations(Loops, () => + { + var result1 = Math.Min(DoublePositive1, DoubleNegative1); + var result2 = Math.Min(DoublePositive2, DoublePositive1); + var result3 = Math.Min(double.NaN, DoublePositive2); + }); + } + + [Benchmark] + public void Min_Float() + { + RunIterations(Loops, () => + { + var result1 = Math.Min(FloatPositive1, FloatNegative1); + var result2 = Math.Min(FloatPositive2, FloatPositive1); + var result3 = Math.Min(float.NaN, FloatPositive2); + }); + } + + [Benchmark] + public void Min_Int() + { + RunIterations(Loops, () => + { + var result1 = Math.Min(IntPositive1, IntNegative1); + var result2 = Math.Min(IntPositive2, IntPositive1); + var result3 = Math.Min(IntNegative1, IntPositive2); + }); + } + } +} diff --git a/nanoFramework.System.Math.Benchmark/Program.cs b/nanoFramework.System.Math.Benchmark/Program.cs index f394e8d..45f520e 100644 --- a/nanoFramework.System.Math.Benchmark/Program.cs +++ b/nanoFramework.System.Math.Benchmark/Program.cs @@ -1,15 +1,26 @@ -using nanoFramework.Benchmark; -using System; using System.Diagnostics; +using System; using System.Threading; +using nanoFramework.Benchmark; -namespace nanoFramework.System.Math.Benchmark +namespace MathBenchmarks { public class Program { public static void Main() { - BenchmarkRunner.Run(typeof(IAssemblyHandler).Assembly); +#if DEBUG + Console.WriteLine("Benchmarks should be run in a release build."); + Debugger.Break(); + return; +#endif + Console.WriteLine("Running benchmarks..."); + + BenchmarkRunner.RunClass(typeof(MaxBenchmarks)); + BenchmarkRunner.RunClass(typeof(MinBenchmarks)); + + BenchmarkRunner.RunClass(typeof(MathBenchmark)); + Thread.Sleep(Timeout.Infinite); } } diff --git a/nanoFramework.System.Math.Benchmark/nanoFramework.System.Math.Benchmark.nfproj b/nanoFramework.System.Math.Benchmark/nanoFramework.System.Math.Benchmark.nfproj index 698fd41..4210617 100644 --- a/nanoFramework.System.Math.Benchmark/nanoFramework.System.Math.Benchmark.nfproj +++ b/nanoFramework.System.Math.Benchmark/nanoFramework.System.Math.Benchmark.nfproj @@ -12,7 +12,7 @@ Exe Properties 512 - nanoFramework.System.Math.Benchmark + MathBenchmarks nanoFramework.System.Math.Benchmark v1.0 true @@ -20,48 +20,45 @@ + + + - + + + + ..\packages\nanoFramework.CoreLibrary.1.14.2\lib\mscorlib.dll - True - + ..\packages\nanoFramework.Benchmark.1.0.56\lib\nanoFramework.Benchmark.dll - True - + ..\packages\nanoFramework.Logging.1.1.63\lib\nanoFramework.Logging.dll - True - + ..\packages\nanoFramework.Runtime.Native.1.6.6\lib\nanoFramework.Runtime.Native.dll - True - + ..\packages\nanoFramework.System.Collections.1.5.18\lib\nanoFramework.System.Collections.dll - True - + ..\packages\nanoFramework.System.Text.1.2.37\lib\nanoFramework.System.Text.dll - True - + ..\packages\nanoFramework.System.Diagnostics.Stopwatch.1.2.325\lib\System.Diagnostics.Stopwatch.dll - True - - Core - + diff --git a/nanoFramework.System.Math/Math.cs b/nanoFramework.System.Math/Math.cs index 7bf2ba8..07de68f 100644 --- a/nanoFramework.System.Math/Math.cs +++ b/nanoFramework.System.Math/Math.cs @@ -353,7 +353,7 @@ public static ulong Clamp( /// Parameter or , whichever is larger. public static int Max(int val1, int val2) { - return MathInternal.Max(val1, val2); + return (val1 >= val2) ? val1 : val2; } /// @@ -373,10 +373,8 @@ public static int Max(int val1, int val2) /// The first of two single-precision floating-point numbers to compare. /// The second of two single-precision floating-point numbers to compare. /// Parameter or , whichever is larger. If , or , or both and are equal to , is returned. - public static float Max(float val1, float val2) - { - return (float)Max((double)val1, val2); - } + [MethodImpl(MethodImplOptions.InternalCall)] + public static extern float Max(float val1, float val2); /// /// Returns the smaller of two 32-bit signed integers. @@ -386,7 +384,7 @@ public static float Max(float val1, float val2) /// Parameter or , whichever is smaller. public static int Min(int val1, int val2) { - return MathInternal.Min(val1, val2); + return (val2 >= val1) ? val1 : val2; } /// @@ -406,10 +404,8 @@ public static int Min(int val1, int val2) /// The first of two single-precision floating-point numbers to compare. /// The second of two single-precision floating-point numbers to compare. /// Parameter or , whichever is smaller. If , , or both and are equal to , is returned. - public static float Min(float val1, float val2) - { - return (float)Min((double)val1, val2); - } + [MethodImpl(MethodImplOptions.InternalCall)] + public static extern float Min(float val1, float val2); /// /// Returns a specified number raised to the specified power. diff --git a/nanoFramework.System.Math/Properties/AssemblyInfo.cs b/nanoFramework.System.Math/Properties/AssemblyInfo.cs index b20857c..bc927f5 100644 --- a/nanoFramework.System.Math/Properties/AssemblyInfo.cs +++ b/nanoFramework.System.Math/Properties/AssemblyInfo.cs @@ -12,6 +12,6 @@ //////////////////////////////////////////////////////////////// // update this whenever the native assembly signature changes // -[assembly: AssemblyNativeVersion("100.0.5.4")] +[assembly: AssemblyNativeVersion("100.0.5.5")] //////////////////////////////////////////////////////////////// diff --git a/nanoFramework.System.Math/nanoFramework.System.Math.nfproj b/nanoFramework.System.Math/nanoFramework.System.Math.nfproj index 59afdf6..1e3becd 100644 --- a/nanoFramework.System.Math/nanoFramework.System.Math.nfproj +++ b/nanoFramework.System.Math/nanoFramework.System.Math.nfproj @@ -13,7 +13,7 @@ Library Properties 512 - Sytem + System System.Math v1.0 True @@ -51,9 +51,11 @@ - + + + + ..\packages\nanoFramework.CoreLibrary.1.14.2\lib\mscorlib.dll - True