if (!IsIntrinsicImplementedByUserCall(intrinsicName))
#endif
{
+ CORINFO_CLASS_HANDLE tmpClass;
+ CORINFO_ARG_LIST_HANDLE arg;
+ var_types op1Type;
+ var_types op2Type;
+
switch (sig->numArgs)
{
case 1:
op1 = impPopStack().val;
- assert(varTypeIsFloating(op1));
+ arg = sig->args;
+ op1Type = JITtype2varType(strip(info.compCompHnd->getArgType(sig, arg, &tmpClass)));
- if (op1->TypeGet() != callType)
+ if (op1->TypeGet() != genActualType(op1Type))
{
+ assert(varTypeIsFloating(op1));
op1 = gtNewCastNode(callType, op1, false, callType);
}
op2 = impPopStack().val;
op1 = impPopStack().val;
- assert(varTypeIsFloating(op1));
- assert(varTypeIsFloating(op2));
+ arg = sig->args;
+ op1Type = JITtype2varType(strip(info.compCompHnd->getArgType(sig, arg, &tmpClass)));
- if (op2->TypeGet() != callType)
+ if (op1->TypeGet() != genActualType(op1Type))
{
- op2 = gtNewCastNode(callType, op2, false, callType);
+ assert(varTypeIsFloating(op1));
+ op1 = gtNewCastNode(callType, op1, false, callType);
}
- if (op1->TypeGet() != callType)
+
+ arg = info.compCompHnd->getArgNext(arg);
+ op2Type = JITtype2varType(strip(info.compCompHnd->getArgType(sig, arg, &tmpClass)));
+
+ if (op2->TypeGet() != genActualType(op2Type))
{
- op1 = gtNewCastNode(callType, op1, false, callType);
+ assert(varTypeIsFloating(op2));
+ op2 = gtNewCastNode(callType, op2, false, callType);
}
op1 = new (this, GT_INTRINSIC) GenTreeIntrinsic(genActualType(callType), op1, op2,
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+
+namespace System.MathBenchmarks
+{
+ public partial class Double
+ {
+ // Tests Math.Abs(double) over 5000 iterations for the domain -1, +1
+
+ private const double absDelta = 0.0004;
+ private const double absExpectedResult = 2499.9999999999659;
+
+ public void Abs() => AbsTest();
+
+ public static void AbsTest()
+ {
+ double result = 0.0, value = -1.0;
+
+ for (int iteration = 0; iteration < MathTests.Iterations; iteration++)
+ {
+ value += absDelta;
+ result += Math.Abs(value);
+ }
+
+ double diff = Math.Abs(absExpectedResult - result);
+
+ if (diff > MathTests.DoubleEpsilon)
+ {
+ throw new Exception($"Expected Result {absExpectedResult,20:g17}; Actual Result {result,20:g17}");
+ }
+ }
+ }
+}
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+
+namespace System.MathBenchmarks
+{
+ public partial class Double
+ {
+ // Tests Math.Acos(double) over 5000 iterations for the domain -1, +1
+
+ private const double acosDelta = 0.0004;
+ private const double acosExpectedResult = 7852.4108380716079;
+
+ public void Acos() => AcosTest();
+
+ public static void AcosTest()
+ {
+ double result = 0.0, value = -1.0;
+
+ for (int iteration = 0; iteration < MathTests.Iterations; iteration++)
+ {
+ value += acosDelta;
+ result += Math.Acos(value);
+ }
+
+ double diff = Math.Abs(acosExpectedResult - result);
+
+ if (diff > MathTests.DoubleEpsilon)
+ {
+ throw new Exception($"Expected Result {acosExpectedResult,20:g17}; Actual Result {result,20:g17}");
+ }
+ }
+ }
+}
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+
+namespace System.MathBenchmarks
+{
+ public partial class Double
+ {
+ // Tests Math.Acosh(double) over 5000 iterations for the domain +1, +3
+
+ private const double acoshDelta = 0.0004;
+ private const double acoshExpectedResult = 6148.648751739127;
+
+ public void Acosh() => AcoshTest();
+
+ public static void AcoshTest()
+ {
+ double result = 0.0, value = 1.0;
+
+ for (int iteration = 0; iteration < MathTests.Iterations; iteration++)
+ {
+ result += Math.Acosh(value);
+ value += acoshDelta;
+ }
+
+ double diff = Math.Abs(acoshExpectedResult - result);
+
+ if (double.IsNaN(result) || (diff > MathTests.DoubleEpsilon))
+ {
+ throw new Exception($"Expected Result {acoshExpectedResult,20:g17}; Actual Result {result,20:g17}");
+ }
+ }
+ }
+}
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+
+namespace System.MathBenchmarks
+{
+ public partial class Double
+ {
+ // Tests Math.Asin(double) over 5000 iterations for the domain -1, +1
+
+ private const double asinDelta = 0.0004;
+ private const double asinExpectedResult = 1.5707959028763392;
+
+ public void Asin() => AsinTest();
+
+ public static void AsinTest()
+ {
+ double result = 0.0, value = -1.0;
+
+ for (int iteration = 0; iteration < MathTests.Iterations; iteration++)
+ {
+ value += asinDelta;
+ result += Math.Asin(value);
+ }
+
+ double diff = Math.Abs(asinExpectedResult - result);
+
+ if (diff > MathTests.DoubleEpsilon)
+ {
+ throw new Exception($"Expected Result {asinExpectedResult,20:g17}; Actual Result {result,20:g17}");
+ }
+ }
+ }
+}
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+
+namespace System.MathBenchmarks
+{
+ public partial class Double
+ {
+ // Tests Math.Asinh(double) over 5000 iterations for the domain -1, +1
+
+ private const double asinhDelta = 0.0004;
+ private const double asinhExpectedResult = -0.88137358721605752;
+
+ public void Asinh() => AsinhTest();
+
+ public static void AsinhTest()
+ {
+ double result = 0.0, value = -1.0;
+
+ for (int iteration = 0; iteration < MathTests.Iterations; iteration++)
+ {
+ result += Math.Asinh(value);
+ value += asinhDelta;
+ }
+
+ double diff = Math.Abs(asinhExpectedResult - result);
+
+ if (double.IsNaN(result) || (diff > MathTests.DoubleEpsilon))
+ {
+ throw new Exception($"Expected Result {asinhExpectedResult,20:g17}; Actual Result {result,20:g17}");
+ }
+ }
+ }
+}
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+
+namespace System.MathBenchmarks
+{
+ public partial class Double
+ {
+ // Tests Math.Atan2(double, double) over 5000 iterations for the domain y: -1, +1; x: +1, -1
+
+ private const double atan2DeltaX = -0.0004;
+ private const double atan2DeltaY = 0.0004;
+ private const double atan2ExpectedResult = 3926.99081698702;
+
+ public void Atan2() => Atan2Test();
+
+ public static void Atan2Test()
+ {
+ double result = 0.0, valueX = 1.0, valueY = -1.0;
+
+ for (int iteration = 0; iteration < MathTests.Iterations; iteration++)
+ {
+ valueX += atan2DeltaX; valueY += atan2DeltaY;
+ result += Math.Atan2(valueY, valueX);
+ }
+
+ double diff = Math.Abs(atan2ExpectedResult - result);
+
+ if (diff > MathTests.DoubleEpsilon)
+ {
+ throw new Exception($"Expected Result {atan2ExpectedResult,20:g17}; Actual Result {result,20:g17}");
+ }
+ }
+ }
+}
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+
+namespace System.MathBenchmarks
+{
+ public partial class Double
+ {
+ // Tests Math.Atan(double) over 5000 iterations for the domain -1, +1
+
+ private const double atanDelta = 0.0004;
+ private const double atanExpectedResult = 0.78539816322061329;
+
+ public void Atan() => AtanTest();
+
+ public static void AtanTest()
+ {
+ double result = 0.0, value = -1.0;
+
+ for (int iteration = 0; iteration < MathTests.Iterations; iteration++)
+ {
+ value += atanDelta;
+ result += Math.Atan(value);
+ }
+
+ double diff = Math.Abs(atanExpectedResult - result);
+
+ if (diff > MathTests.DoubleEpsilon)
+ {
+ throw new Exception($"Expected Result {atanExpectedResult,20:g17}; Actual Result {result,20:g17}");
+ }
+ }
+ }
+}
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+
+namespace System.MathBenchmarks
+{
+ public partial class Double
+ {
+ // Tests Math.Atanh(double) over 5000 iterations for the domain -1, +1
+
+ private const double atanhDelta = 0.0004;
+ private const double atanhExpectedResult = float.NegativeInfinity;
+
+ public void Atanh() => AtanhTest();
+
+ public static void AtanhTest()
+ {
+ double result = 0.0, value = -1.0;
+
+ for (int iteration = 0; iteration < MathTests.Iterations; iteration++)
+ {
+ result += Math.Atanh(value);
+ value += atanhDelta;
+ }
+
+ double diff = Math.Abs(atanhExpectedResult - result);
+
+ if (double.IsNaN(result) || (diff > MathTests.DoubleEpsilon))
+ {
+ throw new Exception($"Expected Result {atanhExpectedResult,20:g17}; Actual Result {result,20:g17}");
+ }
+ }
+ }
+}
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+
+namespace System.MathBenchmarks
+{
+ public partial class Double
+ {
+ // Tests Math.Cbrt(double) over 5000 iterations for the domain +0, +PI
+
+ private const double cbrtDelta = 0.0006283185307180;
+ private const double cbrtExpectedResult = 5491.4635361574383;
+
+ public void Cbrt() => CbrtTest();
+
+ public static void CbrtTest()
+ {
+ double result = 0.0, value = 0.0;
+
+ for (int iteration = 0; iteration < MathTests.Iterations; iteration++)
+ {
+ result += Math.Cbrt(value);
+ value += cbrtDelta;
+ }
+
+ double diff = Math.Abs(cbrtExpectedResult - result);
+
+ if (double.IsNaN(result) || (diff > MathTests.DoubleEpsilon))
+ {
+ throw new Exception($"Expected Result {cbrtExpectedResult,20:g17}; Actual Result {result,20:g17}");
+ }
+ }
+ }
+}
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+
+namespace System.MathBenchmarks
+{
+ public partial class Double
+ {
+ // Tests Math.Ceiling(double) over 5000 iterations for the domain -1, +1
+
+ private const double ceilingDelta = 0.0004;
+ private const double ceilingExpectedResult = 2500;
+
+ public void Ceiling() => CeilingTest();
+
+ public static void CeilingTest()
+ {
+ double result = 0.0, value = -1.0;
+
+ for (int iteration = 0; iteration < MathTests.Iterations; iteration++)
+ {
+ value += ceilingDelta;
+ result += Math.Ceiling(value);
+ }
+
+ double diff = Math.Abs(ceilingExpectedResult - result);
+
+ if (diff > MathTests.DoubleEpsilon)
+ {
+ throw new Exception($"Expected Result {ceilingExpectedResult,20:g17}; Actual Result {result,20:g17}");
+ }
+ }
+ }
+}
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+
+namespace System.MathBenchmarks
+{
+ public partial class Double
+ {
+ // Tests Math.CopySign(double) over 5000 iterations for the domain -1, +1
+
+ private const double copySignDelta = 0.0004;
+ private const int copySignExpectedResult = 0;
+
+ public void CopySign() => CopySignTest();
+
+ public static void CopySignTest()
+ {
+ double result = 1.0, value = -1.0;
+
+ for (int iteration = 0; iteration < MathTests.Iterations; iteration++)
+ {
+ value += copySignDelta;
+ result += Math.CopySign(result, value);
+ }
+
+ if (result != copySignExpectedResult)
+ {
+ throw new Exception($"Expected Result {copySignExpectedResult}; Actual Result {result}");
+ }
+ }
+ }
+}
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+
+namespace System.MathBenchmarks
+{
+ public partial class Double
+ {
+ // Tests Math.Cos(double) over 5000 iterations for the domain 0, PI
+
+ private const double cosDoubleDelta = 0.0006283185307180;
+ private const double cosDoubleExpectedResult = -1.0000000005924159;
+
+ public void Cos() => CosDoubleTest();
+
+ public static void CosDoubleTest()
+ {
+ double result = 0.0, value = 0.0;
+
+ for (int iteration = 0; iteration < MathTests.Iterations; iteration++)
+ {
+ value += cosDoubleDelta;
+ result += Math.Cos(value);
+ }
+
+ double diff = Math.Abs(cosDoubleExpectedResult - result);
+
+ if (diff > MathTests.DoubleEpsilon)
+ {
+ throw new Exception($"Expected Result {cosDoubleExpectedResult,20:g17}; Actual Result {result,20:g17}");
+ }
+ }
+ }
+}
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+
+namespace System.MathBenchmarks
+{
+ public partial class Double
+ {
+ // Tests Math.Cosh(double) over 5000 iterations for the domain -1, +1
+
+ private const double coshDelta = 0.0004;
+ private const double coshExpectedResult = 5876.0060465657216;
+
+ public void Cosh() => CoshTest();
+
+ public static void CoshTest()
+ {
+ double result = 0.0, value = -1.0;
+
+ for (int iteration = 0; iteration < MathTests.Iterations; iteration++)
+ {
+ value += coshDelta;
+ result += Math.Cosh(value);
+ }
+
+ double diff = Math.Abs(coshExpectedResult - result);
+
+ if (diff > MathTests.DoubleEpsilon)
+ {
+ throw new Exception($"Expected Result {coshExpectedResult,20:g17}; Actual Result {result,20:g17}");
+ }
+ }
+ }
+}
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+
+namespace System.MathBenchmarks
+{
+ public partial class Double
+ {
+ // Tests Math.Exp(double) over 5000 iterations for the domain -1, +1
+
+ private const double expDelta = 0.0004;
+ private const double expExpectedResult = 5877.1812477590884;
+
+ public void Exp() => ExpTest();
+
+ public static void ExpTest()
+ {
+ double result = 0.0, value = -1.0;
+
+ for (int iteration = 0; iteration < MathTests.Iterations; iteration++)
+ {
+ value += expDelta;
+ result += Math.Exp(value);
+ }
+
+ double diff = Math.Abs(expExpectedResult - result);
+
+ if (diff > MathTests.DoubleEpsilon)
+ {
+ throw new Exception($"Expected Result {expExpectedResult,20:g17}; Actual Result {result,20:g17}");
+ }
+ }
+ }
+}
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+
+namespace System.MathBenchmarks
+{
+ public partial class Double
+ {
+ // Tests Math.Floor(double) over 5000 iterations for the domain -1, +1
+
+ private const double floorDelta = 0.0004;
+ private const double floorExpectedResult = -2500;
+
+ public void Floor() => FloorTest();
+
+ public static void FloorTest()
+ {
+ double result = 0.0, value = -1.0;
+
+ for (int iteration = 0; iteration < MathTests.Iterations; iteration++)
+ {
+ value += floorDelta;
+ result += Math.Floor(value);
+ }
+
+ double diff = Math.Abs(floorExpectedResult - result);
+
+ if (diff > MathTests.DoubleEpsilon)
+ {
+ throw new Exception($"Expected Result {floorExpectedResult,20:g17}; Actual Result {result,20:g17}");
+ }
+ }
+ }
+}
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+
+namespace System.MathBenchmarks
+{
+ public partial class Double
+ {
+ // Tests Math.FusedMultiplyAdd(double, double, double) over 5000 iterations for the domain x: +2, +1; y: -2, -1, z: +1, -1
+
+ private const double fusedMultiplyAddDeltaX = -0.0004;
+ private const double fusedMultiplyAddDeltaY = 0.0004;
+ private const double fusedMultiplyAddDeltaZ = -0.0004;
+ private const double fusedMultiplyAddExpectedResult = -6667.6668000005066;
+
+ public void FusedMultiplyAdd() => FusedMultiplyAddTest();
+
+ public static void FusedMultiplyAddTest()
+ {
+ double result = 0.0, valueX = 2.0, valueY = -2.0, valueZ = 1.0;
+
+ for (int iteration = 0; iteration < MathTests.Iterations; iteration++)
+ {
+ result += Math.FusedMultiplyAdd(valueX, valueY, valueZ);
+ valueX += fusedMultiplyAddDeltaX; valueY += fusedMultiplyAddDeltaY; valueZ += fusedMultiplyAddDeltaZ;
+ }
+
+ double diff = Math.Abs(fusedMultiplyAddExpectedResult - result);
+
+ if (double.IsNaN(result) || (diff > MathTests.DoubleEpsilon))
+ {
+ throw new Exception($"Expected Result {fusedMultiplyAddExpectedResult,20:g17}; Actual Result {result,20:g17}");
+ }
+ }
+ }
+}
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+
+namespace System.MathBenchmarks
+{
+ public partial class Double
+ {
+ // Tests Math.ILogB(double) over 5000 iterations for the domain +1, +3
+
+ private const double iLogBDelta = 0.0004;
+ private const int iLogBExpectedResult = 2499;
+
+ public void ILogB() => ILogBTest();
+
+ public static void ILogBTest()
+ {
+ int result = 0;
+ double value = 1.0;
+
+ for (int iteration = 0; iteration < MathTests.Iterations; iteration++)
+ {
+ result += Math.ILogB(value);
+ value += iLogBDelta;
+ }
+
+ if (result != iLogBExpectedResult)
+ {
+ throw new Exception($"Expected Result {iLogBExpectedResult,20:g17}; Actual Result {result,20:g17}");
+ }
+ }
+ }
+}
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+
+namespace System.MathBenchmarks
+{
+ public partial class Double
+ {
+ // Tests Math.Log10(double) over 5000 iterations for the domain -1, +1
+
+ private const double log10Delta = 0.0004;
+ private const double log10ExpectedResult = -664.07384902184072;
+
+ /// <summary>
+ /// this benchmark is dependent on loop alignment
+ /// </summary>
+ public void Log10() => Log10Test();
+
+ public static void Log10Test()
+ {
+ double result = 0.0, value = 0.0;
+
+ for (int iteration = 0; iteration < MathTests.Iterations; iteration++)
+ {
+ value += log10Delta;
+ result += Math.Log10(value);
+ }
+
+ double diff = Math.Abs(log10ExpectedResult - result);
+
+ if (diff > MathTests.DoubleEpsilon)
+ {
+ throw new Exception($"Expected Result {log10ExpectedResult,20:g17}; Actual Result {result,20:g17}");
+ }
+ }
+ }
+}
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+
+namespace System.MathBenchmarks
+{
+ public partial class Double
+ {
+ // Tests Math.Log2(double) over 5000 iterations for the domain +1, +3
+
+ private const double log2Delta = 0.0004;
+ private const double log2ExpectedResult = 4672.9510376532398;
+
+ public void Log2() => Log2Test();
+
+ public static void Log2Test()
+ {
+ double result = 0.0, value = 1.0;
+
+ for (int iteration = 0; iteration < MathTests.Iterations; iteration++)
+ {
+ result += Math.Log2(value);
+ value += log2Delta;
+ }
+
+ double diff = Math.Abs(log2ExpectedResult - result);
+
+ if (double.IsNaN(result) || (diff > MathTests.DoubleEpsilon))
+ {
+ throw new Exception($"Expected Result {log2ExpectedResult,20:g17}; Actual Result {result,20:g17}");
+ }
+ }
+ }
+}
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+
+namespace System.MathBenchmarks
+{
+ public partial class Double
+ {
+ // Tests Math.Log(double) over 5000 iterations for the domain -1, +1
+
+ private const double logDelta = 0.0004;
+ private const double logExpectedResult = -1529.0865454048721;
+
+ public void Log() => LogTest();
+
+ public static void LogTest()
+ {
+ double result = 0.0, value = 0.0;
+
+ for (int iteration = 0; iteration < MathTests.Iterations; iteration++)
+ {
+ value += logDelta;
+ result += Math.Log(value);
+ }
+
+ double diff = Math.Abs(logExpectedResult - result);
+
+ if (diff > MathTests.DoubleEpsilon)
+ {
+ throw new Exception($"Expected Result {logExpectedResult,20:g17}; Actual Result {result,20:g17}");
+ }
+ }
+ }
+
+}
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+
+namespace System.MathBenchmarks
+{
+ public partial class Double
+ {
+ // Tests Math.Min(double) over 5000 iterations for the domain -1, +1
+
+ private const double maxDelta = 0.0004;
+ private const double maxExpectedResult = -1.0;
+
+ public void Max() => MaxTest();
+
+ public static void MaxTest()
+ {
+ double result = 0.0, val1 = -1.0, val2 = -1.0 - maxDelta;
+
+ for (int iteration = 0; iteration < MathTests.Iterations; iteration++)
+ {
+ val2 += maxDelta;
+ result += Math.Max(val1, val2);
+ }
+
+ double diff = Math.Abs(maxExpectedResult - result);
+
+ if (diff > MathTests.DoubleEpsilon)
+ {
+ throw new Exception($"Expected Result {maxExpectedResult,20:g17}; Actual Result {result,20:g17}");
+ }
+ }
+ }
+}
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+
+namespace System.MathBenchmarks
+{
+ public partial class Double
+ {
+ // Tests Math.Min(double) over 5000 iterations for the domain -1, +1
+
+ private const double minDelta = 0.0004;
+ private const double minExpectedResult = 1.0;
+
+ public void Min() => MinTest();
+
+ public static void MinTest()
+ {
+ double result = 0.0, val1 = 1.0, val2 = 1.0 + minDelta;
+
+ for (int iteration = 0; iteration < MathTests.Iterations; iteration++)
+ {
+ val2 -= minDelta;
+ result += Math.Min(val1, val2);
+ }
+
+ double diff = Math.Abs(minExpectedResult - result);
+
+ if (diff > MathTests.DoubleEpsilon)
+ {
+ throw new Exception($"Expected Result {minExpectedResult,20:g17}; Actual Result {result,20:g17}");
+ }
+ }
+ }
+}
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+
+namespace System.MathBenchmarks
+{
+ public partial class Double
+ {
+ // Tests Math.Pow(double, double) over 5000 iterations for the domain x: +2, +1; y: -2, -1
+
+ private const double powDeltaX = -0.0004;
+ private const double powDeltaY = 0.0004;
+ private const double powExpectedResult = 4659.4627376138733;
+
+ public void Pow() => PowTest();
+
+ public static void PowTest()
+ {
+ double result = 0.0, valueX = 2.0, valueY = -2.0;
+
+ for (int iteration = 0; iteration < MathTests.Iterations; iteration++)
+ {
+ valueX += powDeltaX; valueY += powDeltaY;
+ result += Math.Pow(valueX, valueY);
+ }
+
+ double diff = Math.Abs(powExpectedResult - result);
+
+ if (diff > MathTests.DoubleEpsilon)
+ {
+ throw new Exception($"Expected Result {powExpectedResult,20:g17}; Actual Result {result,20:g17}");
+ }
+ }
+ }
+}
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+
+namespace System.MathBenchmarks
+{
+ public partial class Double
+ {
+ // Tests Math.Round(double) over 5000 iterations for the domain -PI/2, +PI/2
+
+ private const double roundDelta = 0.0006283185307180;
+ private const double roundExpectedResult = 2;
+
+ public void Round() => RoundTest();
+
+ public static void RoundTest()
+ {
+ double result = 0.0, value = -1.5707963267948966;
+
+ for (int iteration = 0; iteration < MathTests.Iterations; iteration++)
+ {
+ value += roundDelta;
+ result += Math.Round(value);
+ }
+
+ double diff = Math.Abs(roundExpectedResult - result);
+
+ if (diff > MathTests.DoubleEpsilon)
+ {
+ throw new Exception($"Expected Result {roundExpectedResult,20:g17}; Actual Result {result,20:g17}");
+ }
+ }
+ }
+}
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+
+namespace System.MathBenchmarks
+{
+ public partial class Double
+ {
+ // Tests Math.ScaleB(double, int) over 5000 iterations for the domain x: -1, +1; y: +0, +5000
+
+ private const double scaleBDeltaX = -0.0004;
+ private const int scaleBDeltaY = 1;
+ private const double scaleBExpectedResult = double.NegativeInfinity;
+
+ public void ScaleB() => ScaleBTest();
+
+ public static void ScaleBTest()
+ {
+ double result = 0.0, valueX = -1.0;
+ int valueY = 1;
+
+ for (int iteration = 0; iteration < MathTests.Iterations; iteration++)
+ {
+ result += Math.ScaleB(valueX, valueY);
+ valueX += scaleBDeltaX; valueY += scaleBDeltaY;
+ }
+
+ double diff = Math.Abs(scaleBExpectedResult - result);
+
+ if (double.IsNaN(result) || (diff > MathTests.DoubleEpsilon))
+ {
+ throw new Exception($"Expected Result {scaleBExpectedResult,20:g17}; Actual Result {result,20:g17}");
+ }
+ }
+ }
+}
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+
+namespace System.MathBenchmarks
+{
+ public partial class Double
+ {
+ // Tests Math.Sin(double) over 5000 iterations for the domain -PI/2, +PI/2
+
+ private const double sinDelta = 0.0006283185307180;
+ private const double sinExpectedResult = 1.0000000005445053;
+
+ public void Sin() => SinTest();
+
+ public static void SinTest()
+ {
+ double result = 0.0, value = -1.5707963267948966;
+
+ for (int iteration = 0; iteration < MathTests.Iterations; iteration++)
+ {
+ value += sinDelta;
+ result += Math.Sin(value);
+ }
+
+ double diff = Math.Abs(sinExpectedResult - result);
+
+ if (diff > MathTests.DoubleEpsilon)
+ {
+ throw new Exception($"Expected Result {sinExpectedResult,20:g17}; Actual Result {result,20:g17}");
+ }
+ }
+ }
+}
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+
+namespace System.MathBenchmarks
+{
+ public partial class Double
+ {
+ // Tests Math.Sinh(double) over 5000 iterations for the domain -1, +1
+
+ private const double sinhDelta = 0.0004;
+ private const double sinhExpectedResult = 1.17520119337903;
+
+ public void Sinh() => SinhTest();
+
+ public static void SinhTest()
+ {
+ double result = 0.0, value = -1.0;
+
+ for (int iteration = 0; iteration < MathTests.Iterations; iteration++)
+ {
+ value += sinhDelta;
+ result += Math.Sinh(value);
+ }
+
+ double diff = Math.Abs(sinhExpectedResult - result);
+
+ if (diff > MathTests.DoubleEpsilon)
+ {
+ throw new Exception($"Expected Result {sinhExpectedResult,20:g17}; Actual Result {result,20:g17}");
+ }
+ }
+ }
+}
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+
+namespace System.MathBenchmarks
+{
+ public partial class Double
+ {
+ // Tests Math.Sqrt(double) over 5000 iterations for the domain 0, PI
+
+ private const double sqrtDelta = 0.0006283185307180;
+ private const double sqrtExpectedResult = 5909.0605337797215;
+
+ public void Sqrt() => SqrtTest();
+
+ public static void SqrtTest()
+ {
+ double result = 0.0, value = 0.0;
+
+ for (int iteration = 0; iteration < MathTests.Iterations; iteration++)
+ {
+ value += sqrtDelta;
+ result += Math.Sqrt(value);
+ }
+
+ double diff = Math.Abs(sqrtExpectedResult - result);
+
+ if (diff > MathTests.DoubleEpsilon)
+ {
+ throw new Exception($"Expected Result {sqrtExpectedResult,20:g17}; Actual Result {result,20:g17}");
+ }
+ }
+ }
+}
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+
+namespace System.MathBenchmarks
+{
+ public partial class Double
+ {
+ // Tests Math.Tan(double) over 5000 iterations for the domain -PI/2, +PI/2
+
+ private const double tanDelta = 0.0004;
+ private const double tanExpectedResult = 1.5574077243051505;
+
+ public void Tan() => TanTest();
+
+ public static void TanTest()
+ {
+ double result = 0.0, value = -1.0;
+
+ for (int iteration = 0; iteration < MathTests.Iterations; iteration++)
+ {
+ value += tanDelta;
+ result += Math.Tan(value);
+ }
+
+ double diff = Math.Abs(tanExpectedResult - result);
+
+ if (diff > MathTests.DoubleEpsilon)
+ {
+ throw new Exception($"Expected Result {tanExpectedResult,20:g17}; Actual Result {result,20:g17}");
+ }
+ }
+ }
+}
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+
+namespace System.MathBenchmarks
+{
+ public partial class Double
+ {
+ // Tests Math.Tanh(double) over 5000 iterations for the domain -1, +1
+
+ private const double tanhDelta = 0.0004;
+ private const double tanhExpectedResult = 0.76159415578341827;
+
+ public void Tanh() => TanhTest();
+
+ public static void TanhTest()
+ {
+ double result = 0.0, value = -1.0;
+
+ for (int iteration = 0; iteration < MathTests.Iterations; iteration++)
+ {
+ value += tanhDelta;
+ result += Math.Tanh(value);
+ }
+
+ double diff = Math.Abs(tanhExpectedResult - result);
+
+ if (diff > MathTests.DoubleEpsilon)
+ {
+ throw new Exception($"Expected Result {tanhExpectedResult,20:g17}; Actual Result {result,20:g17}");
+ }
+ }
+ }
+}
--- /dev/null
+<Project Sdk="Microsoft.NET.Sdk">
+ <PropertyGroup>
+ <OutputType>Exe</OutputType>
+ </PropertyGroup>
+ <PropertyGroup>
+ <DebugType>None</DebugType>
+ <Optimize />
+ </PropertyGroup>
+ <ItemGroup>
+ <Compile Include="**/*.cs" />
+ </ItemGroup>
+</Project>
--- /dev/null
+<Project Sdk="Microsoft.NET.Sdk">
+ <PropertyGroup>
+ <OutputType>Exe</OutputType>
+ </PropertyGroup>
+ <PropertyGroup>
+ <DebugType>None</DebugType>
+ <Optimize>True</Optimize>
+ </PropertyGroup>
+ <ItemGroup>
+ <Compile Include="**/*.cs" />
+ </ItemGroup>
+</Project>
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+namespace System.MathBenchmarks
+{
+ public partial class MathTests
+ {
+ // double has a machine epsilon of approx: 2.22e-16. However, due to floating-point precision
+ // errors, this is too accurate when aggregating values of a set of iterations. Using the
+ // single-precision machine epsilon as our epsilon should be 'good enough' for the purposes
+ // of the perf testing as it ensures we get the expected value and that it is at least as precise
+ // as we would have computed with the single-precision version of the function (without aggregation).
+ public const double DoubleEpsilon = 1.19e-07;
+
+ // 5000 iterations is enough to cover the full domain of inputs for certain functions (such
+ // as Cos, which has a domain of 0 to PI) at reasonable intervals (in the case of Cos, the
+ // interval is PI / 5000 which is 0.0006283185307180). It should also give reasonable coverage
+ // for functions which have a larger domain (such as Atan, which covers the full set of real numbers).
+ public const int Iterations = 5000;
+
+ // float has a machine epsilon of approx: 1.19e-07. However, due to floating-point precision
+ // errors, this is too accurate when aggregating values of a set of iterations. Using the
+ // half-precision machine epsilon as our epsilon should be 'good enough' for the purposes
+ // of the perf testing as it ensures we get the expected value and that it is at least as precise
+ // as we would have computed with the half-precision version of the function (without aggregation).
+ public const float SingleEpsilon = 9.77e-04f;
+ }
+}
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+namespace System.MathBenchmarks
+{
+ public partial class MathTests
+ {
+ public static int Main(string[] args)
+ {
+ var result = 100;
+
+ var doubleTests = new Double();
+ result += Test(doubleTests.Abs);
+ result += Test(doubleTests.Acos);
+ result += Test(doubleTests.Acosh);
+ result += Test(doubleTests.Asin);
+ result += Test(doubleTests.Asinh);
+ result += Test(doubleTests.Atan);
+ result += Test(doubleTests.Atanh);
+ result += Test(doubleTests.Atan2);
+ result += Test(doubleTests.Cbrt);
+ result += Test(doubleTests.Ceiling);
+ result += Test(doubleTests.CopySign);
+ result += Test(doubleTests.Cos);
+ result += Test(doubleTests.Cosh);
+ result += Test(doubleTests.Exp);
+ result += Test(doubleTests.Floor);
+ result += Test(doubleTests.FusedMultiplyAdd);
+ result += Test(doubleTests.ILogB);
+ result += Test(doubleTests.Log);
+ result += Test(doubleTests.Log2);
+ result += Test(doubleTests.Log10);
+ result += Test(doubleTests.Max);
+ result += Test(doubleTests.Min);
+ result += Test(doubleTests.Pow);
+ result += Test(doubleTests.Round);
+ result += Test(doubleTests.ScaleB);
+ result += Test(doubleTests.Sin);
+ result += Test(doubleTests.Sinh);
+ result += Test(doubleTests.Sqrt);
+ result += Test(doubleTests.Tan);
+ result += Test(doubleTests.Tanh);
+
+ var singleTests = new Single();
+ result += Test(singleTests.Abs);
+ result += Test(singleTests.Acos);
+ result += Test(singleTests.Acosh);
+ result += Test(singleTests.Asin);
+ result += Test(singleTests.Asinh);
+ result += Test(singleTests.Atan);
+ result += Test(singleTests.Atanh);
+ result += Test(singleTests.Atan2);
+ result += Test(singleTests.Cbrt);
+ result += Test(singleTests.Ceiling);
+ result += Test(singleTests.CopySign);
+ result += Test(singleTests.Cos);
+ result += Test(singleTests.Cosh);
+ result += Test(singleTests.Exp);
+ result += Test(singleTests.Floor);
+ result += Test(singleTests.FusedMultiplyAdd);
+ result += Test(singleTests.ILogB);
+ result += Test(singleTests.Log);
+ result += Test(singleTests.Log2);
+ result += Test(singleTests.Log10);
+ result += Test(singleTests.Max);
+ result += Test(singleTests.Min);
+ result += Test(singleTests.Pow);
+ result += Test(singleTests.Round);
+ result += Test(singleTests.ScaleB);
+ result += Test(singleTests.Sin);
+ result += Test(singleTests.Sinh);
+ result += Test(singleTests.Sqrt);
+ result += Test(singleTests.Tan);
+ result += Test(singleTests.Tanh);
+
+ return result;
+ }
+
+ private static int Test(Action action)
+ {
+ try
+ {
+ action();
+ }
+ catch
+ {
+ return -1;
+ }
+
+ return 0;
+ }
+ }
+}
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+
+namespace System.MathBenchmarks
+{
+ public partial class Single
+ {
+ // Tests Math.Abs(single) over 5000 iterations for the domain -1, +1
+
+ private const float absDelta = 0.0004f;
+ private const float absExpectedResult = 2500.03125f;
+
+ public void Abs() => AbsTest();
+
+ public static void AbsTest()
+ {
+ float result = 0.0f, value = -1.0f;
+
+ for (int iteration = 0; iteration < MathTests.Iterations; iteration++)
+ {
+ value += absDelta;
+ result += Math.Abs(value);
+ }
+
+ float diff = Math.Abs(absExpectedResult - result);
+
+ if (diff > MathTests.SingleEpsilon)
+ {
+ throw new Exception($"Expected Result {absExpectedResult,10:g9}; Actual Result {result,10:g9}");
+ }
+ }
+ }
+}
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+
+namespace System.MathBenchmarks
+{
+ public partial class Single
+ {
+ // Tests MathF.Acos(float) over 5000 iterations for the domain -1, +1
+
+ private const float acosDelta = 0.0004f;
+ private const float acosExpectedResult = 7852.41084f;
+
+ public void Acos() => AcosTest();
+
+ public static void AcosTest()
+ {
+ float result = 0.0f, value = -1.0f;
+
+ for (int iteration = 0; iteration < MathTests.Iterations; iteration++)
+ {
+ value += acosDelta;
+ result += MathF.Acos(value);
+ }
+
+ float diff = MathF.Abs(acosExpectedResult - result);
+
+ if (diff > MathTests.SingleEpsilon)
+ {
+ throw new Exception($"Expected Result {acosExpectedResult,10:g9}; Actual Result {result,10:g9}");
+ }
+ }
+ }
+}
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+
+namespace System.MathBenchmarks
+{
+ public partial class Single
+ {
+ // Tests MathF.Acosh(float) over 5000 iterations for the domain +1, +3
+
+ private const float acoshDelta = 0.0004f;
+ private const float acoshExpectedResult = 6148.45459f;
+
+ public void Acosh() => AcoshTest();
+
+ public static void AcoshTest()
+ {
+ float result = 0.0f, value = 1.0f;
+
+ for (int iteration = 0; iteration < MathTests.Iterations; iteration++)
+ {
+ result += MathF.Acosh(value);
+ value += acoshDelta;
+ }
+
+ float diff = MathF.Abs(acoshExpectedResult - result);
+
+ if (float.IsNaN(result) || (diff > MathTests.SingleEpsilon))
+ {
+ throw new Exception($"Expected Result {acoshExpectedResult,10:g9}; Actual Result {result,10:g9}");
+ }
+ }
+ }
+}
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+
+namespace System.MathBenchmarks
+{
+ public partial class Single
+ {
+ // Tests MathF.Asin(float) over 5000 iterations for the domain -1, +1
+
+ private const float asinDelta = 0.0004f;
+ private const float asinExpectedResult = 1.57079590f;
+
+ public void Asin() => AsinTest();
+
+ public static void AsinTest()
+ {
+ float result = 0.0f, value = -1.0f;
+
+ for (int iteration = 0; iteration < MathTests.Iterations; iteration++)
+ {
+ value += asinDelta;
+ result += MathF.Asin(value);
+ }
+
+ float diff = MathF.Abs(asinExpectedResult - result);
+
+ if (diff > MathTests.SingleEpsilon)
+ {
+ throw new Exception($"Expected Result {asinExpectedResult,10:g9}; Actual Result {result,10:g9}");
+ }
+ }
+ }
+}
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+
+namespace System.MathBenchmarks
+{
+ public partial class Single
+ {
+ // Tests MathF.Asinh(float) over 5000 iterations for the domain -1, +1
+
+ private const float asinhDelta = 0.0004f;
+ private const float asinhExpectedResult = -0.814757347f;
+
+ public void Asinh() => AsinhTest();
+
+ public static void AsinhTest()
+ {
+ float result = 0.0f, value = -1.0f;
+
+ for (int iteration = 0; iteration < MathTests.Iterations; iteration++)
+ {
+ result += MathF.Asinh(value);
+ value += asinhDelta;
+ }
+
+ float diff = MathF.Abs(asinhExpectedResult - result);
+
+ if (float.IsNaN(result) || (diff > MathTests.SingleEpsilon))
+ {
+ throw new Exception($"Expected Result {asinhExpectedResult,10:g9}; Actual Result {result,10:g9}");
+ }
+ }
+ }
+}
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+
+namespace System.MathBenchmarks
+{
+ public partial class Single
+ {
+ // Tests MathF.Atan2(float, float) over 5000 iterations for the domain y: -1, +1; x: +1, -1
+
+ private const float atan2DeltaX = -0.0004f;
+ private const float atan2DeltaY = 0.0004f;
+ private const float atan2ExpectedResult = 3930.14282f;
+
+ public void Atan2() => Atan2Test();
+
+ public static void Atan2Test()
+ {
+ float result = 0.0f, valueX = 1.0f, valueY = -1.0f;
+
+ for (int iteration = 0; iteration < MathTests.Iterations; iteration++)
+ {
+ valueX += atan2DeltaX; valueY += atan2DeltaY;
+ result += MathF.Atan2(valueY, valueX);
+ }
+
+ float diff = MathF.Abs(atan2ExpectedResult - result);
+
+ if (diff > MathTests.SingleEpsilon)
+ {
+ throw new Exception($"Expected Result {atan2ExpectedResult,10:g9}; Actual Result {result,10:g9}");
+ }
+ }
+ }
+}
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+
+namespace System.MathBenchmarks
+{
+ public partial class Single
+ {
+ // Tests MathF.Atan(float) over 5000 iterations for the domain -1, +1
+
+ private const float atanDelta = 0.0004f;
+ private const float atanExpectedResult = 0.841940999f;
+
+ public void Atan() => AtanTest();
+
+ public static void AtanTest()
+ {
+ float result = 0.0f, value = -1.0f;
+
+ for (int iteration = 0; iteration < MathTests.Iterations; iteration++)
+ {
+ value += atanDelta;
+ result += MathF.Atan(value);
+ }
+
+ float diff = MathF.Abs(atanExpectedResult - result);
+
+ if (diff > MathTests.SingleEpsilon)
+ {
+ throw new Exception($"Expected Result {atanExpectedResult,10:g9}; Actual Result {result,10:g9}");
+ }
+ }
+ }
+}
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+
+namespace System.MathBenchmarks
+{
+ public partial class Single
+ {
+ // Tests MathF.Atanh(float) over 5000 iterations for the domain -1, +1
+
+ private const float atanhDelta = 0.0004f;
+ private const float atanhExpectedResult = float.NegativeInfinity;
+
+ public void Atanh() => AtanhTest();
+
+ public static void AtanhTest()
+ {
+ float result = 0.0f, value = -1.0f;
+
+ for (int iteration = 0; iteration < MathTests.Iterations; iteration++)
+ {
+ result += MathF.Atanh(value);
+ value += atanhDelta;
+ }
+
+ float diff = MathF.Abs(atanhExpectedResult - result);
+
+ if (float.IsNaN(result) || (diff > MathTests.SingleEpsilon))
+ {
+ throw new Exception($"Expected Result {atanhExpectedResult,10:g9}; Actual Result {result,10:g9}");
+ }
+ }
+ }
+}
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+
+namespace System.MathBenchmarks
+{
+ public partial class Single
+ {
+ // Tests MathF.Cbrt(float) over 5000 iterations for the domain +0, +PI
+
+ private const float cbrtDelta = 0.000628318531f;
+ private const float cbrtExpectedResult = 5491.4541f;
+
+ public void Cbrt() => CbrtTest();
+
+ public static void CbrtTest()
+ {
+ float result = 0.0f, value = 0.0f;
+
+ for (int iteration = 0; iteration < MathTests.Iterations; iteration++)
+ {
+ result += MathF.Cbrt(value);
+ value += cbrtDelta;
+ }
+
+ float diff = MathF.Abs(cbrtExpectedResult - result);
+
+ if (float.IsNaN(result) || (diff > MathTests.SingleEpsilon))
+ {
+ throw new Exception($"Expected Result {cbrtExpectedResult,10:g9}; Actual Result {result,10:g9}");
+ }
+ }
+ }
+}
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+
+namespace System.MathBenchmarks
+{
+ public partial class Single
+ {
+ // Tests MathF.Ceiling(float) over 5000 iterations for the domain -1, +1
+
+ private const float ceilingDelta = 0.0004f;
+ private const float ceilingExpectedResult = 2502.0f;
+
+ public void Ceiling() => CeilingTest();
+
+ public static void CeilingTest()
+ {
+ float result = 0.0f, value = -1.0f;
+
+ for (int iteration = 0; iteration < MathTests.Iterations; iteration++)
+ {
+ value += ceilingDelta;
+ result += MathF.Ceiling(value);
+ }
+
+ float diff = MathF.Abs(ceilingExpectedResult - result);
+
+ if (diff > MathTests.SingleEpsilon)
+ {
+ throw new Exception($"Expected Result {ceilingExpectedResult,10:g9}; Actual Result {result,10:g9}");
+ }
+ }
+ }
+}
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+
+namespace System.MathBenchmarks
+{
+ public partial class Single
+ {
+ // Tests Math.CopySign(float) over 5000 iterations for the domain -1, +1
+
+ private const float copySignDelta = 0.0004f;
+ private const int copySignExpectedResult = 0;
+
+ public void CopySign() => CopySignTest();
+
+ public static void CopySignTest()
+ {
+ float result = 1.0f, value = -1.0f;
+
+ for (int iteration = 0; iteration < MathTests.Iterations; iteration++)
+ {
+ value += copySignDelta;
+ result += MathF.CopySign(result, value);
+ }
+
+ if (result != copySignExpectedResult)
+ {
+ throw new Exception($"Expected Result {copySignExpectedResult}; Actual Result {result}");
+ }
+ }
+ }
+}
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+
+namespace System.MathBenchmarks
+{
+ public partial class Single
+ {
+ // Tests MathF.Cos(float) over 5000 iterations for the domain 0, PI
+
+ private const float cosDelta = 0.000628318531f;
+ private const float cosExpectedResult = -0.993487537f;
+
+ public void Cos() => CosTest();
+
+ public static void CosTest()
+ {
+ float result = 0.0f, value = 0.0f;
+
+ for (int iteration = 0; iteration < MathTests.Iterations; iteration++)
+ {
+ value += cosDelta;
+ result += MathF.Cos(value);
+ }
+
+ float diff = MathF.Abs(cosExpectedResult - result);
+
+ if (diff > MathTests.SingleEpsilon)
+ {
+ throw new Exception($"Expected Result {cosExpectedResult,10:g9}; Actual Result {result,10:g9}");
+ }
+ }
+ }
+}
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+
+namespace System.MathBenchmarks
+{
+ public partial class Single
+ {
+ // Tests MathF.Cosh(float) over 5000 iterations for the domain -1, +1
+
+ private const float coshDelta = 0.0004f;
+ private const float coshExpectedResult = 5876.02588f;
+
+ public void Cosh() => CoshTest();
+
+ public static void CoshTest()
+ {
+ float result = 0.0f, value = -1.0f;
+
+ for (int iteration = 0; iteration < MathTests.Iterations; iteration++)
+ {
+ value += coshDelta;
+ result += MathF.Cosh(value);
+ }
+
+ float diff = MathF.Abs(coshExpectedResult - result);
+
+ if (diff > MathTests.SingleEpsilon)
+ {
+ throw new Exception($"Expected Result {coshExpectedResult,10:g9}; Actual Result {result,10:g9}");
+ }
+ }
+ }
+}
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+
+namespace System.MathBenchmarks
+{
+ public partial class Single
+ {
+ // Tests MathF.Exp(float) over 5000 iterations for the domain -1, +1
+
+ private const float expDelta = 0.0004f;
+ private const float expExpectedResult = 5877.28564f;
+
+ public void Exp() => ExpTest();
+
+ public static void ExpTest()
+ {
+ float result = 0.0f, value = -1.0f;
+
+ for (int iteration = 0; iteration < MathTests.Iterations; iteration++)
+ {
+ value += expDelta;
+ result += MathF.Exp(value);
+ }
+
+ float diff = MathF.Abs(expExpectedResult - result);
+
+ if (diff > MathTests.SingleEpsilon)
+ {
+ throw new Exception($"Expected Result {expExpectedResult,10:g9}; Actual Result {result,10:g9}");
+ }
+ }
+ }
+}
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+
+namespace System.MathBenchmarks
+{
+ public partial class Single
+ {
+ // Tests MathF.Floor(float) over 5000 iterations for the domain -1, +1
+
+ private const float floorDelta = 0.0004f;
+ private const float floorExpectedResult = -2498.0f;
+
+ public void Floor() => FloorTest();
+
+ public static void FloorTest()
+ {
+ float result = 0.0f, value = -1.0f;
+
+ for (int iteration = 0; iteration < MathTests.Iterations; iteration++)
+ {
+ value += floorDelta;
+ result += MathF.Floor(value);
+ }
+
+ float diff = MathF.Abs(floorExpectedResult - result);
+
+ if (diff > MathTests.SingleEpsilon)
+ {
+ throw new Exception($"Expected Result {floorExpectedResult,10:g9}; Actual Result {result,10:g9}");
+ }
+ }
+ }
+}
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+
+namespace System.MathBenchmarks
+{
+ public partial class Single
+ {
+ // Tests MathF.FusedMultiplyAdd(float, float, float) over 5000 iterations for the domain x: +2, +1; y: -2, -1, z: +1, -1
+
+ private const float fusedMultiplyAddDeltaX = -0.0004f;
+ private const float fusedMultiplyAddDeltaY = 0.0004f;
+ private const float fusedMultiplyAddDeltaZ = -0.0004f;
+ private const float fusedMultiplyAddExpectedResult = -6668.49072f;
+
+ public void FusedMultiplyAdd() => FusedMultiplyAddTest();
+
+ public static void FusedMultiplyAddTest()
+ {
+ float result = 0.0f, valueX = 2.0f, valueY = -2.0f, valueZ = 1.0f;
+
+ for (int iteration = 0; iteration < MathTests.Iterations; iteration++)
+ {
+ result += MathF.FusedMultiplyAdd(valueX, valueY, valueZ);
+ valueX += fusedMultiplyAddDeltaX; valueY += fusedMultiplyAddDeltaY; valueZ += fusedMultiplyAddDeltaZ;
+ }
+
+ float diff = MathF.Abs(fusedMultiplyAddExpectedResult - result);
+
+ if (float.IsNaN(result) || (diff > MathTests.SingleEpsilon))
+ {
+ throw new Exception($"Expected Result {fusedMultiplyAddExpectedResult,10:g9}; Actual Result {result,10:g9}");
+ }
+ }
+ }
+}
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+
+namespace System.MathBenchmarks
+{
+ public partial class Single
+ {
+ // Tests MathF.ILogB(float) over 5000 iterations for the domain +1, +3
+
+ private const float iLogBDelta = 0.0004f;
+ private const int iLogBExpectedResult = 2499;
+
+ public void ILogB() => ILogBTest();
+
+ public static void ILogBTest()
+ {
+ int result = 0;
+ float value = 1.0f;
+
+ for (int iteration = 0; iteration < MathTests.Iterations; iteration++)
+ {
+ result += MathF.ILogB(value);
+ value += iLogBDelta;
+ }
+
+ if (result != iLogBExpectedResult)
+ {
+ throw new Exception($"Expected Result {iLogBExpectedResult,10:g9}; Actual Result {result,10:g9}");
+ }
+ }
+ }
+}
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+
+namespace System.MathBenchmarks
+{
+ public partial class Single
+ {
+ // Tests MathF.Log10(float) over 5000 iterations for the domain -1, +1
+
+ private const float log10Delta = 0.0004f;
+ private const float log10ExpectedResult = -664.094971f;
+
+ /// <summary>
+ /// this benchmark is dependent on loop alignment
+ /// </summary>
+ public void Log10() => Log10Test();
+
+ public static void Log10Test()
+ {
+ float result = 0.0f, value = 0.0f;
+
+ for (int iteration = 0; iteration < MathTests.Iterations; iteration++)
+ {
+ value += log10Delta;
+ result += MathF.Log10(value);
+ }
+
+ float diff = MathF.Abs(log10ExpectedResult - result);
+
+ if (diff > MathTests.SingleEpsilon)
+ {
+ throw new Exception($"Expected Result {log10ExpectedResult,10:g9}; Actual Result {result,10:g9}");
+ }
+ }
+ }
+}
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+
+namespace System.MathBenchmarks
+{
+ public partial class Single
+ {
+ // Tests MathF.Log2(float) over 5000 iterations for the domain +1, +3
+
+ private const float log2Delta = 0.0004f;
+ private const float log2ExpectedResult = 4672.73193f;
+
+ public void Log2() => Log2Test();
+
+ public static void Log2Test()
+ {
+ float result = 0.0f, value = 1.0f;
+
+ for (int iteration = 0; iteration < MathTests.Iterations; iteration++)
+ {
+ result += MathF.Log2(value);
+ value += log2Delta;
+ }
+
+ float diff = MathF.Abs(log2ExpectedResult - result);
+
+ if (float.IsNaN(result) || (diff > MathTests.SingleEpsilon))
+ {
+ throw new Exception($"Expected Result {log2ExpectedResult,10:g9}; Actual Result {result,10:g9}");
+ }
+ }
+ }
+}
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+
+namespace System.MathBenchmarks
+{
+ public partial class Single
+ {
+ // Tests MathF.Log(float) over 5000 iterations for the domain -1, +1
+
+ private const float logDelta = 0.0004f;
+ private const float logExpectedResult = -1529.14014f;
+
+ public void Log() => LogTest();
+
+ public static void LogTest()
+ {
+ float result = 0.0f, value = 0.0f;
+
+ for (int iteration = 0; iteration < MathTests.Iterations; iteration++)
+ {
+ value += logDelta;
+ result += MathF.Log(value);
+ }
+
+ float diff = MathF.Abs(logExpectedResult - result);
+
+ if (diff > MathTests.SingleEpsilon)
+ {
+ throw new Exception($"Expected Result {logExpectedResult,10:g9}; Actual Result {result,10:g9}");
+ }
+ }
+ }
+
+}
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+
+namespace System.MathBenchmarks
+{
+ public partial class Single
+ {
+ // Tests Math.Min(double) over 5000 iterations for the domain -1, +1
+
+ private const float maxDelta = 0.0004f;
+ private const float maxExpectedResult = -0.9267354f;
+
+ public void Max() => MaxTest();
+
+ public static void MaxTest()
+ {
+ float result = 0.0f, val1 = -1.0f, val2 = -1.0f - maxDelta;
+
+ for (int iteration = 0; iteration < MathTests.Iterations; iteration++)
+ {
+ val2 += maxDelta;
+ result += Math.Max(val1, val2);
+ }
+
+ float diff = Math.Abs(maxExpectedResult - result);
+
+ if (diff > MathTests.SingleEpsilon)
+ {
+ throw new Exception($"Expected Result {maxExpectedResult,10:g9}; Actual Result {result,10:g9}");
+ }
+ }
+ }
+}
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+
+namespace System.MathBenchmarks
+{
+ public partial class Single
+ {
+ // Tests Math.Min(double) over 5000 iterations for the domain -1, +1
+
+ private const float minDelta = 0.0004f;
+ private const float minExpectedResult = 0.9267354f;
+
+ public void Min() => MinTest();
+
+ public static void MinTest()
+ {
+ float result = 0.0f, val1 = 1.0f, val2 = 1.0f + minDelta;
+
+ for (int iteration = 0; iteration < MathTests.Iterations; iteration++)
+ {
+ val2 -= minDelta;
+ result += Math.Min(val1, val2);
+ }
+
+ float diff = Math.Abs(minExpectedResult - result);
+
+ if (diff > MathTests.SingleEpsilon)
+ {
+ throw new Exception($"Expected Result {minExpectedResult,10:g9}; Actual Result {result,10:g9}");
+ }
+ }
+ }
+}
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+
+namespace System.MathBenchmarks
+{
+ public partial class Single
+ {
+ // Tests MathF.Pow(float, float) over 5000 iterations for the domain x: +2, +1; y: -2, -1
+
+ private const float powDeltaX = -0.0004f;
+ private const float powDeltaY = 0.0004f;
+ private const float powExpectedResult = 4659.30762f;
+
+ public void Pow() => PowTest();
+
+ public static void PowTest()
+ {
+ float result = 0.0f, valueX = 2.0f, valueY = -2.0f;
+
+ for (int iteration = 0; iteration < MathTests.Iterations; iteration++)
+ {
+ valueX += powDeltaX; valueY += powDeltaY;
+ result += MathF.Pow(valueX, valueY);
+ }
+
+ float diff = MathF.Abs(powExpectedResult - result);
+
+ if (diff > MathTests.SingleEpsilon)
+ {
+ throw new Exception($"Expected Result {powExpectedResult,10:g9}; Actual Result {result,10:g9}");
+ }
+ }
+ }
+}
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+
+namespace System.MathBenchmarks
+{
+ public partial class Single
+ {
+ // Tests MathF.Round(float) over 5000 iterations for the domain -PI/2, +PI/2
+
+ private const float roundDelta = 0.000628318531f;
+ private const float roundExpectedResult = 2.0f;
+
+ public void Round() => RoundTest();
+
+ public static void RoundTest()
+ {
+ float result = 0.0f, value = -1.57079633f;
+
+ for (int iteration = 0; iteration < MathTests.Iterations; iteration++)
+ {
+ value += roundDelta;
+ result += MathF.Round(value);
+ }
+
+ float diff = MathF.Abs(roundExpectedResult - result);
+
+ if (diff > MathTests.SingleEpsilon)
+ {
+ throw new Exception($"Expected Result {roundExpectedResult,10:g9}; Actual Result {result,10:g9}");
+ }
+ }
+ }
+}
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+
+namespace System.MathBenchmarks
+{
+ public partial class Single
+ {
+ // Tests MathF.ScaleB(float, int) over 5000 iterations for the domain x: -1, +1; y: +0, +5000
+
+ private const float scaleBDeltaX = -0.0004f;
+ private const int scaleBDeltaY = 1;
+ private const float scaleBExpectedResult = float.NegativeInfinity;
+
+ public void ScaleB() => ScaleBTest();
+
+ public static void ScaleBTest()
+ {
+ float result = 0.0f, valueX = -1.0f;
+ int valueY = 0;
+
+ for (int iteration = 0; iteration < MathTests.Iterations; iteration++)
+ {
+ result += MathF.ScaleB(valueX, valueY);
+ valueX += scaleBDeltaX; valueY += scaleBDeltaY;
+ }
+
+ float diff = MathF.Abs(scaleBExpectedResult - result);
+
+ if (float.IsNaN(result) || (diff > MathTests.SingleEpsilon))
+ {
+ throw new Exception($"Expected Result {scaleBExpectedResult,10:g9}; Actual Result {result,10:g9}");
+ }
+ }
+ }
+}
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+
+namespace System.MathBenchmarks
+{
+ public partial class Single
+ {
+ // Tests MathF.Sin(float) over 5000 iterations for the domain -PI/2, +PI/2
+
+ private const float sinDelta = 0.000628318531f;
+ private const float sinExpectedResult = 1.03592682f;
+
+ public void Sin() => SinTest();
+
+ public static void SinTest()
+ {
+ float result = 0.0f, value = -1.57079633f;
+
+ for (int iteration = 0; iteration < MathTests.Iterations; iteration++)
+ {
+ value += sinDelta;
+ result += MathF.Sin(value);
+ }
+
+ float diff = MathF.Abs(sinExpectedResult - result);
+
+ if (diff > MathTests.SingleEpsilon)
+ {
+ throw new Exception($"Expected Result {sinExpectedResult,10:g9}; Actual Result {result,10:g9}");
+ }
+ }
+ }
+}
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+
+namespace System.MathBenchmarks
+{
+ public partial class Single
+ {
+ // Tests MathF.Sinh(float) over 5000 iterations for the domain -1, +1
+
+ private const float sinhDelta = 0.0004f;
+ private const float sinhExpectedResult = 1.26028216f;
+
+ /// <summary>
+ /// this benchmark is dependent on loop alignment
+ /// </summary>
+ public void Sinh() => SinhTest();
+
+ public static void SinhTest()
+ {
+ float result = 0.0f, value = -1.0f;
+
+ for (int iteration = 0; iteration < MathTests.Iterations; iteration++)
+ {
+ value += sinhDelta;
+ result += MathF.Sinh(value);
+ }
+
+ float diff = MathF.Abs(sinhExpectedResult - result);
+
+ if (diff > MathTests.SingleEpsilon)
+ {
+ throw new Exception($"Expected Result {sinhExpectedResult,10:g9}; Actual Result {result,10:g9}");
+ }
+ }
+ }
+}
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+
+namespace System.MathBenchmarks
+{
+ public partial class Single
+ {
+ // Tests MathF.Sqrt(float) over 5000 iterations for the domain 0, PI
+
+ private const float sqrtDelta = 0.000628318531f;
+ private const float sqrtExpectedResult = 5909.03027f;
+
+ public void Sqrt() => SqrtTest();
+
+ public static void SqrtTest()
+ {
+ float result = 0.0f, value = 0.0f;
+
+ for (int iteration = 0; iteration < MathTests.Iterations; iteration++)
+ {
+ value += sqrtDelta;
+ result += MathF.Sqrt(value);
+ }
+
+ float diff = MathF.Abs(sqrtExpectedResult - result);
+
+ if (diff > MathTests.SingleEpsilon)
+ {
+ throw new Exception($"Expected Result {sqrtExpectedResult,10:g9}; Actual Result {result,10:g9}");
+ }
+ }
+ }
+}
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+
+namespace System.MathBenchmarks
+{
+ public partial class Single
+ {
+ // Tests MathF.Tan(float) over 5000 iterations for the domain -PI/2, +PI/2
+
+ private const float tanDelta = 0.0004f;
+ private const float tanExpectedResult = 1.66717815f;
+
+ public void Tan() => TanTest();
+
+ public static void TanTest()
+ {
+ float result = 0.0f, value = -1.0f;
+
+ for (int iteration = 0; iteration < MathTests.Iterations; iteration++)
+ {
+ value += tanDelta;
+ result += MathF.Tan(value);
+ }
+
+ float diff = MathF.Abs(tanExpectedResult - result);
+
+ if (diff > MathTests.SingleEpsilon)
+ {
+ throw new Exception($"Expected Result {tanExpectedResult,10:g9}; Actual Result {result,10:g9}");
+ }
+ }
+ }
+}
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+
+namespace System.MathBenchmarks
+{
+ public partial class Single
+ {
+ // Tests MathF.Tanh(float) over 5000 iterations for the domain -1, +1
+
+ private const float tanhDelta = 0.0004f;
+ private const float tanhExpectedResult = 0.816701353f;
+
+ public void Tanh() => TanhTest();
+
+ public static void TanhTest()
+ {
+ float result = 0.0f, value = -1.0f;
+
+ for (int iteration = 0; iteration < MathTests.Iterations; iteration++)
+ {
+ value += tanhDelta;
+ result += MathF.Tanh(value);
+ }
+
+ float diff = MathF.Abs(tanhExpectedResult - result);
+
+ if (diff > MathTests.SingleEpsilon)
+ {
+ throw new Exception($"Expected Result {tanhExpectedResult,10:g9}; Actual Result {result,10:g9}");
+ }
+ }
+ }
+}