Esempio n. 1
0
        private static void TestBinaryOperationFloatApproximate(float a, float b, float expected, BinaryOperationType op)
        {
            BinaryOperation func   = binaryOperations[(int)op];
            sfloat          result = func((sfloat)a, (sfloat)b);

            if (float.IsNaN(expected) && result.IsNaN())
            {
                // special case, NaN-s cannot be compared
                return;
            }

            if (float.IsInfinity(expected) && result.IsInfinity() && MathF.Sign(expected) == result.Sign())
            {
                // both are the same infinities
                return;
            }

            float allowedError = MathF.Max(1e-6f * MathF.Pow(2.0f, MathF.Log2(MathF.Abs(expected) + 1.0f)), 1e-6f);
            float difference   = MathF.Abs((float)result - expected);
            bool  isOk         = difference < allowedError;

            Debug.Assert(isOk);
        }
Esempio n. 2
0
        private static void TestUnaryOperationFloatApproximate(float x, float expected, UnaryOperationType op, float allowedErrorMultiplier = 1.0f)
        {
            UnaryOperation func   = unaryOperations[(int)op];
            sfloat         result = func((sfloat)x);

            if (float.IsNaN(expected) && result.IsNaN())
            {
                // special case, NaN-s cannot be compared
                return;
            }

            if (float.IsInfinity(expected) && result.IsInfinity() && MathF.Sign(expected) == result.Sign())
            {
                // both are the same infinities
                return;
            }

            float allowedError = MathF.Max(1e-6f * allowedErrorMultiplier * MathF.Pow(2.0f, MathF.Log2(MathF.Abs(expected) + 1.0f)), 1e-6f);

            float difference = MathF.Abs((float)result - expected);
            bool  isOk       = difference <= allowedError;

            if (!isOk && (op == UnaryOperationType.Round || op == UnaryOperationType.Floor || op == UnaryOperationType.Ceiling))
            {
                // Because of the loss of precision that can result from representing decimal values
                // as floating-point numbers or performing arithmetic operations on floating-point values,
                // in some cases the Round method may not appear to round midpoint values to the nearest even integer.
                // https://docs.microsoft.com/en-us/dotnet/api/system.math.round

                if (MathF.Abs(x % 1.0f) - 0.5f < 0.01f)
                {
                    // x is near a midpoint, it's possible that rounding happened in a different direction
                    isOk = MathF.Abs((float)result - expected) <= 1.0f;
                }
            }

            Debug.Assert(isOk);
        }