/**
         * @overload static bool AreEqual(float first, float second, float marginOfError, int ulpTolerance)
         * */
        public static bool AreEqual(float first, float second, float marginOfError, int ulpTolerance)
        {
            // When numbers are very close to zero, this initial check of absolute values is needed. Otherwise
            // we can safely use the ULP difference.
            float absoluteDiff = Math.Abs(first - second);

            if (absoluteDiff <= marginOfError)
            {
                return(true);
            }

            SingleInfo firstInfo  = new SingleInfo(first);
            SingleInfo secondInfo = new SingleInfo(second);

            // Different signs mean the numbers don't match, period.
            if (firstInfo.IsNegative != secondInfo.IsNegative)
            {
                return(false);
            }

            // Find the difference in ULPs (unit of least precision).
            int ulpDiff = Math.Abs(firstInfo.Bits - secondInfo.Bits);

            if (ulpDiff <= ulpTolerance)
            {
                return(true);
            }

            return(false);
        }
        /**
         * @overload static int Boundary(float value, float marginOfError, int ulpTolerance, int boundaryScale)
         * */
        public static int Boundary(float value, float marginOfError, int ulpTolerance, int boundaryScale)
        {
            SingleInfo valueInfo          = new SingleInfo(Math.Abs(value));
            SingleInfo valueWithErrorInfo = new SingleInfo(Math.Abs(value) + marginOfError);

            int ulpBoundary    = ulpTolerance * boundaryScale;
            int marginBoundary = (valueWithErrorInfo.Bits - valueInfo.Bits) * boundaryScale;

            return(Math.Max(ulpBoundary, marginBoundary));
        }
        /**
         * @overload static int ULPDistance(float first, float second)
         * */
        public static int ULPDistance(float first, float second)
        {
            SingleInfo firstInfo  = new SingleInfo(first);
            SingleInfo secondInfo = new SingleInfo(second);

            if (firstInfo.IsNegative != secondInfo.IsNegative)
            {
                throw new ArgumentException("Numbers have mixed signs; cannot calculate the ULP distance across the 0 boundary.");
            }

            return(Math.Abs(firstInfo.Bits - secondInfo.Bits));
        }
        /**
         * @overload static float ULP(float value)
         * */
        public static float ULP(float value)
        {
            if (Single.IsNaN(value))
            {
                return(Single.NaN);
            }
            else if (Single.IsPositiveInfinity(value) || Single.IsNegativeInfinity(value))
            {
                return(Single.PositiveInfinity);
            }
            else if (value == 0.0)
            {
                return(Single.Epsilon);
            }
            else if (Math.Abs(value) == Single.MaxValue)
            {
                return(MaxFloatULP);
            }

            SingleInfo info = new SingleInfo(value);

            return(Math.Abs((float)(info.Bits + 1) - value));
        }
예제 #5
0
 public SingleInfo(float value)
 {
     _value = value;
     _bits  = SingleInfo.SingleToInt32Bits(value);
 }