private static void RandomTestTrigonometryOperation(UnaryOperationType op) { Func <float, float> func = op switch { UnaryOperationType.Sine => MathF.Sin, UnaryOperationType.Cosine => MathF.Cos, UnaryOperationType.Tangent => MathF.Tan, _ => throw new ArgumentException(), }; PCG rand = new PCG(0, 0); // small values for (int i = 0; i < RandomTestCount; ++i) { float x = rand.FloatInclusive(-1.0f, 1.0f); TestTrigonometryOperationApproximate(x, func(x), op); } // medium values for (int i = 0; i < RandomTestCount; ++i) { float x = rand.FloatInclusive(-100.0f, 100.0f); TestTrigonometryOperationApproximate(x, func(x), op); } }
private static void RandomTestBinaryOperation(BinaryOperationType op) { Func <float, float, float> func = op switch { BinaryOperationType.Addition => (float a, float b) => a + b, BinaryOperationType.Subtraction => (float a, float b) => a - b, BinaryOperationType.Multiplication => (float a, float b) => a * b, BinaryOperationType.Division => (float a, float b) => a / b, BinaryOperationType.Modulus => (float a, float b) => a % b, BinaryOperationType.Power => MathF.Pow, BinaryOperationType.ArcTangent2 => MathF.Atan2, _ => throw new ArgumentException(), }; PCG rand = new PCG(0, 0); // very small values for (int i = 0; i < RandomTestCount; ++i) { float a = rand.FloatInclusive(-1e-10f, 1e-10f); float b = rand.FloatInclusive(-1e-10f, 1e-10f); TestBinaryOperationFloatApproximate(a, b, func(a, b), op); } // small values for (int i = 0; i < RandomTestCount; ++i) { float a = rand.FloatInclusive(-1.0f, 1.0f); float b = rand.FloatInclusive(-1.0f, 1.0f); TestBinaryOperationFloatApproximate(a, b, func(a, b), op); } // large values for (int i = 0; i < RandomTestCount; ++i) { float a = rand.FloatInclusive(-100000.0f, 100000.0f); float b = rand.FloatInclusive(-100000.0f, 100000.0f); TestBinaryOperationFloatApproximate(a, b, func(a, b), op); } // huge values for (int i = 0; i < RandomTestCount; ++i) { float a = rand.FloatInclusive(-1000000000.0f, 1000000000.0f); float b = rand.FloatInclusive(-1000000000.0f, 1000000000.0f); TestBinaryOperationFloatApproximate(a, b, func(a, b), op); } // gigantic values for (int i = 0; i < RandomTestCount; ++i) { float a = rand.FloatInclusive(-1e38f, 1e38f); float b = rand.FloatInclusive(-1e38f, 1e38f); TestBinaryOperationFloatApproximate(a, b, func(a, b), op); } }
private static void RandomTestUnaryOperation(UnaryOperationType op, float allowedErrorMultiplier = 1.0f) { Func <float, float> func = op switch { UnaryOperationType.Round => MathF.Round, UnaryOperationType.Floor => MathF.Floor, UnaryOperationType.Ceiling => MathF.Ceiling, UnaryOperationType.Sine => MathF.Sin, UnaryOperationType.Cosine => MathF.Cos, UnaryOperationType.Tangent => MathF.Tan, UnaryOperationType.SquareRoot => MathF.Sqrt, UnaryOperationType.Exponential => MathF.Exp, UnaryOperationType.LogarithmNatural => MathF.Log, UnaryOperationType.LogarithmBase2 => MathF.Log2, UnaryOperationType.ArcSine => MathF.Asin, UnaryOperationType.ArcCosine => MathF.Acos, UnaryOperationType.ArcTangent => MathF.Atan, _ => throw new ArgumentException(), }; PCG rand = new PCG(0, 0); // very small values for (int i = 0; i < RandomTestCount; ++i) { float x = rand.FloatInclusive(-1e-40f, 1e-40f); TestUnaryOperationFloatApproximate(x, func(x), op, allowedErrorMultiplier); } // small values for (int i = 0; i < RandomTestCount; ++i) { float x = rand.FloatInclusive(-1.0f, 1.0f); TestUnaryOperationFloatApproximate(x, func(x), op, allowedErrorMultiplier); } // large values for (int i = 0; i < RandomTestCount; ++i) { float x = rand.FloatInclusive(-100000.0f, 100000.0f); TestUnaryOperationFloatApproximate(x, func(x), op, allowedErrorMultiplier); } // huge values for (int i = 0; i < RandomTestCount; ++i) { float x = rand.FloatInclusive(-1000000000.0f, 1000000000.0f); TestUnaryOperationFloatApproximate(x, func(x), op, allowedErrorMultiplier); } }