/// <summary>
        ///   Reinterprets the memory contents of a floating point value as an integer value
        /// </summary>
        /// <param name="value">
        ///   Floating point value whose memory contents to reinterpret
        /// </param>
        /// <returns>
        ///   The memory contents of the floating point value interpreted as an integer
        /// </returns>
        public static int ReinterpretAsInt(float value)
        {
            FloatIntUnion union = new FloatIntUnion();

            union.Float = value;
            return(union.Int);
        }
        /// <summary>
        ///   Reinterprets the memory contents of an integer as a floating point value
        /// </summary>
        /// <param name="value">Integer value whose memory contents to reinterpret</param>
        /// <returns>
        ///   The memory contents of the integer value interpreted as a floating point value
        /// </returns>
        public static float ReinterpretAsFloat(int value)
        {
            FloatIntUnion union = new FloatIntUnion();

            union.Int = value;
            return(union.Float);
        }
Beispiel #3
0
        /// <summary>
        /// Compares two numbers given some amount of allowed distance.
        /// https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/
        /// </summary>
        /// <param name="x">The first number.</param>
        /// <param name="y">The second number.</param>
        /// <param name="maxUlp">The number of discreet floating point values that are allowed between the two values.</param>
        /// <returns><c>true</c> if the two values are equal, otherwise false.</returns>
        public static bool Equals(float x, float y, int maxUlp)
        {
            if (maxUlp <= 0)
            {
                throw new ArgumentOutOfRangeException("Max Ulp must be greater than 0.");
            }

            FloatIntUnion xUnion = new FloatIntUnion
            {
                Float = x
            };
            FloatIntUnion yUnion = new FloatIntUnion
            {
                Float = y
            };

            // Convert to 2s complement if negative.
            uint xSignMask = xUnion.UInt >> Precision.FLOAT_SHIFT_BITS;
            uint ySignMask = yUnion.UInt >> Precision.FLOAT_SHIFT_BITS;

            uint xTemp = ((Precision.FLOAT_BIT_MASK - xUnion.UInt) & xSignMask);

            xUnion.UInt = xTemp | (xUnion.UInt & ~xSignMask);

            // Convert to 2s complement if negative.
            uint yTemp = ((Precision.FLOAT_BIT_MASK - yUnion.UInt) & ySignMask);

            yUnion.UInt = yTemp | (yUnion.UInt & ~ySignMask);

            // Return if the difference <= maxUlp
            return(Math.Abs(xUnion.Int - yUnion.Int) <= maxUlp);
        }
        public static int ReinterpretAsInt(float value)
        {
            FloatIntUnion floatIntUnion = default(FloatIntUnion);

            floatIntUnion.Float = value;
            return(floatIntUnion.Int);
        }
Beispiel #5
0
    public int FloatToInt(float value)
    {
        var u = new FloatIntUnion();

        u.f = value;
        return(u.i);
    }
        public static float ReinterpretAsFloat(int value)
        {
            FloatIntUnion floatIntUnion = default(FloatIntUnion);

            floatIntUnion.Int = value;
            return(floatIntUnion.Float);
        }
        /// <summary>Compares two floating point values for equality</summary>
        /// <param name="left">First floating point value to be compared</param>
        /// <param name="right">Second floating point value t be compared</param>
        /// <param name="maxUlps">
        ///   Maximum number of representable floating point values that are allowed to
        ///   be between the left and the right floating point values
        /// </param>
        /// <returns>True if both numbers are equal or close to being equal</returns>
        /// <remarks>
        ///   <para>
        ///     Floating point values can only represent a finite subset of natural numbers.
        ///     For example, the values 2.00000000 and 2.00000024 can be stored in a float,
        ///     but nothing between them.
        ///   </para>
        ///   <para>
        ///     This comparison will count how many possible floating point values are between
        ///     the left and the right number. If the number of possible values between both
        ///     numbers is less than or equal to maxUlps, then the numbers are considered as
        ///     being equal.
        ///   </para>
        ///   <para>
        ///     Implementation partially follows the code outlined here:
        ///     http://www.anttirt.net/2007/08/19/proper-floating-point-comparisons/
        ///   </para>
        /// </remarks>
        public static bool AreAlmostEqualUlps(float left, float right, int maxUlps)
        {
            FloatIntUnion leftUnion  = new FloatIntUnion();
            FloatIntUnion rightUnion = new FloatIntUnion();

            leftUnion.Float  = left;
            rightUnion.Float = right;

            uint leftSignMask  = (leftUnion.UInt >> 31);
            uint rightSignMask = (rightUnion.UInt >> 31);

            uint leftTemp = ((0x80000000 - leftUnion.UInt) & leftSignMask);

            leftUnion.UInt = leftTemp | (leftUnion.UInt & ~leftSignMask);

            uint rightTemp = ((0x80000000 - rightUnion.UInt) & rightSignMask);

            rightUnion.UInt = rightTemp | (rightUnion.UInt & ~rightSignMask);

            if (leftSignMask != rightSignMask) // Overflow possible, check each against zero
            {
                if (Math.Abs(leftUnion.Int) > maxUlps || Math.Abs(rightUnion.Int) > maxUlps)
                {
                    return(false);
                }
            }

            // Either they have the same sign or both are very close to zero
            return(Math.Abs(leftUnion.Int - rightUnion.Int) <= maxUlps);
        }
Beispiel #8
0
    public float IntToFloat(int value)
    {
        var u = new FloatIntUnion();

        u.i = value;
        return(u.f);
    }
            public static float ToFloat32(int value)
            {
                FloatIntUnion u = new FloatIntUnion();

                u.i = value;

                return(u.f);
            }
            public static int ToInt32(float value)
            {
                FloatIntUnion u = new FloatIntUnion();

                u.f = value;

                return(u.i);
            }
        internal static ushort Pack(float value)
        {
            var uif = new FloatIntUnion {
                F = value
            };

            return(Pack(uif.I));
        }
        /// <summary>
        /// Prepares a float for network transmission by placing it in the
        /// given byte buffer.  Does not allocate memory like
        /// BitConverter.GetBytes(float).
        /// </summary>
        /// <param name="buffer"></param>
        /// <param name="startInd">Where in the buffer to write the float.</param>
        /// <param name="value">The float to place in the buffer.</param>
        static public void PutFloat(byte[] buffer, int startInd, float value)
        {
            int flt = FloatIntUnion.ToInt32(value);

            buffer[startInd]     = (byte)flt;
            buffer[startInd + 1] = (byte)(flt >> 8);
            buffer[startInd + 2] = (byte)(flt >> 16);
            buffer[startInd + 3] = (byte)(flt >> 24);
        }
Beispiel #13
0
        public static bool AreAlmostEqualUlps(float left, float right, int maxUlps)
        {
            FloatIntUnion floatIntUnion1 = new FloatIntUnion();
            FloatIntUnion floatIntUnion2 = new FloatIntUnion();

            floatIntUnion1.Float = left;
            floatIntUnion2.Float = right;
            uint num1 = floatIntUnion1.UInt >> 31;
            uint num2 = floatIntUnion2.UInt >> 31;
            uint num3 = 2147483648U - floatIntUnion1.UInt & num1;

            floatIntUnion1.UInt = num3 | floatIntUnion1.UInt & ~num1;
            uint num4 = 2147483648U - floatIntUnion2.UInt & num2;

            floatIntUnion2.UInt = num4 | floatIntUnion2.UInt & ~num2;
            return(Math.Abs(floatIntUnion1.Int - floatIntUnion2.Int) <= maxUlps);
        }
        public static bool AreAlmostEqualUlps(float left, float right, int maxUlps)
        {
            FloatIntUnion floatIntUnion  = default(FloatIntUnion);
            FloatIntUnion floatIntUnion2 = default(FloatIntUnion);

            floatIntUnion.Float  = left;
            floatIntUnion2.Float = right;
            uint num  = floatIntUnion.UInt >> 31;
            uint num2 = floatIntUnion2.UInt >> 31;
            uint num3 = (2147483648u - floatIntUnion.UInt) & num;

            floatIntUnion.UInt = num3 | (floatIntUnion.UInt & ~num);
            uint num4 = (2147483648u - floatIntUnion2.UInt) & num2;

            floatIntUnion2.UInt = num4 | (floatIntUnion2.UInt & ~num2);
            return(Math.Abs(floatIntUnion.Int - floatIntUnion2.Int) <= maxUlps);
        }
        /// <summary>Compares two floating point values for equality</summary>
        /// <param name="left">First floating point value to be compared</param>
        /// <param name="right">Second floating point value t be compared</param>
        /// <param name="maxUlps">
        ///   Maximum number of representable floating point values that are allowed to
        ///   be between the left and the right floating point values
        /// </param>
        /// <returns>True if both numbers are equal or close to being equal</returns>
        /// <remarks>
        ///   <para>
        ///     Floating point values can only represent a finite subset of natural numbers.
        ///     For example, the values 2.00000000 and 2.00000024 can be stored in a float,
        ///     but nothing inbetween them.
        ///   </para>
        ///   <para>
        ///     This comparison will count how many possible floating point values are between
        ///     the left and the right number. If the number of possible values between both
        ///     numbers is less than or equal to maxUlps, then the numbers are considered as
        ///     being equal.
        ///   </para>
        ///   <para>
        ///     Implementation partially follows the code outlined here:
        ///     http://www.anttirt.net/2007/08/19/proper-floating-point-comparisons/
        ///   </para>
        /// </remarks>
        public static bool AreAlmostEqualUlps(float left, float right, int maxUlps)
        {
            FloatIntUnion leftUnion = new FloatIntUnion();
            FloatIntUnion rightUnion = new FloatIntUnion();

            leftUnion.Float = left;
            rightUnion.Float = right;

            uint leftSignMask = (leftUnion.UInt >> 31);
            uint rightSignMask = (rightUnion.UInt >> 31);

            uint leftTemp = ((0x80000000 - leftUnion.UInt) & leftSignMask);
            leftUnion.UInt = leftTemp | (leftUnion.UInt & ~leftSignMask);

            uint rightTemp = ((0x80000000 - rightUnion.UInt) & rightSignMask);
            rightUnion.UInt = rightTemp | (rightUnion.UInt & ~rightSignMask);

            return (Math.Abs(leftUnion.Int - rightUnion.Int) <= maxUlps);
        }
        /// <summary>Compares two floating point values for equality</summary>
        /// <param name="left">First floating point value to be compared</param>
        /// <param name="right">Second floating point value t be compared</param>
        /// <param name="maxUlps">
        ///   Maximum number of representable floating point values that are allowed to
        ///   be between the left and the right floating point values
        /// </param>
        /// <returns>True if both numbers are equal or close to being equal</returns>
        /// <remarks>
        ///   <para>
        ///     Floating point values can only represent a finite subset of natural numbers.
        ///     For example, the values 2.00000000 and 2.00000024 can be stored in a float,
        ///     but nothing inbetween them.
        ///   </para>
        ///   <para>
        ///     This comparison will count how many possible floating point values are between
        ///     the left and the right number. If the number of possible values between both
        ///     numbers is less than or equal to maxUlps, then the numbers are considered as
        ///     being equal.
        ///   </para>
        ///   <para>
        ///     Implementation partially follows the code outlined here:
        ///     http://www.anttirt.net/2007/08/19/proper-floating-point-comparisons/
        ///   </para>
        /// </remarks>
        public static bool AreAlmostEqualUlps(float left, float right, int maxUlps)
        {
            FloatIntUnion leftUnion  = new FloatIntUnion();
            FloatIntUnion rightUnion = new FloatIntUnion();

            leftUnion.Float  = left;
            rightUnion.Float = right;

            uint leftSignMask  = (leftUnion.UInt >> 31);
            uint rightSignMask = (rightUnion.UInt >> 31);

            uint leftTemp = ((0x80000000 - leftUnion.UInt) & leftSignMask);

            leftUnion.UInt = leftTemp | (leftUnion.UInt & ~leftSignMask);

            uint rightTemp = ((0x80000000 - rightUnion.UInt) & rightSignMask);

            rightUnion.UInt = rightTemp | (rightUnion.UInt & ~rightSignMask);

            return(Math.Abs(leftUnion.Int - rightUnion.Int) <= maxUlps);
        }
        internal static float Unpack(ushort value)
        {
            uint mantissa = (uint)(value & 1023);
            uint exponent = 0xfffffff2;
            uint result;

            if ((value & -33792) == 0)
            {
                if (mantissa != 0)
                {
                    while ((mantissa & 1024) == 0)
                    {
                        exponent--;
                        mantissa <<= 1;
                    }

                    mantissa &= 0xfffffbff;
                    result    = (((uint)value & 0x8000) << 16) | ((exponent + 127) << 23) | (mantissa << 13);
                }
                else
                {
                    result = (uint)((value & 0x8000) << 16);
                }
            }
            else
            {
                result =
                    (((uint)value & 0x8000) << 16) |
                    (((((uint)value >> 10) & 0x1f) - 15 + 127) << 23) |
                    (mantissa << 13);
            }

            var uif = new FloatIntUnion {
                U = result
            };

            return(uif.F);
        }
        /// <summary>Compares two floating point values for equality</summary>
        /// <param name="left">First floating point value to be compared</param>
        /// <param name="right">Second floating point value t be compared</param>
        /// <param name="maxUlps">
        ///   Maximum number of representable floating point values that are allowed to
        ///   be between the left and the right floating point values
        /// </param>
        /// <returns>True if both numbers are equal or close to being equal</returns>
        /// <remarks>
        ///   <para>
        ///     Floating point values can only represent a finite subset of natural numbers.
        ///     For example, the values 2.00000000 and 2.00000024 can be stored in a float,
        ///     but nothing between them.
        ///   </para>
        ///   <para>
        ///     This comparison will count how many possible floating point values are between
        ///     the left and the right number. If the number of possible values between both
        ///     numbers is less than or equal to maxUlps, then the numbers are considered as
        ///     being equal.
        ///   </para>
        ///   <para>
        ///     Implementation partially follows the code outlined here:
        ///     http://www.anttirt.net/2007/08/19/proper-floating-point-comparisons/
        ///   </para>
        /// </remarks>
        public static bool AreAlmostEqualUlps(float left, float right, int maxUlps)
        {
            FloatIntUnion leftUnion  = new FloatIntUnion();
            FloatIntUnion rightUnion = new FloatIntUnion();

            leftUnion.Float  = left;
            rightUnion.Float = right;

            uint leftSignMask  = (leftUnion.UInt >> 31);
            uint rightSignMask = (rightUnion.UInt >> 31);

            uint leftTemp = ((0x80000000 - leftUnion.UInt) & leftSignMask);

            leftUnion.UInt = leftTemp | (leftUnion.UInt & ~leftSignMask);

            uint rightTemp = ((0x80000000 - rightUnion.UInt) & rightSignMask);

            rightUnion.UInt = rightTemp | (rightUnion.UInt & ~rightSignMask);

            if (leftSignMask != rightSignMask) // Overflow possible, check each against zero
            {
                // This check is specifically used to trap the case of 0 == -0
                // In IEEE floating point maths, -0 is converted to Float.MinValue, which cannot be used with
                // Math.Abs(...) below due to overflow issues. This should only match the 0 == -0 condition.
                if (left == right)
                {
                    return(true);
                }
                if (Math.Abs(leftUnion.Int) > maxUlps || Math.Abs(rightUnion.Int) > maxUlps)
                {
                    return(false);
                }
            }

            // Either they have the same sign or both are very close to zero
            return(Math.Abs(leftUnion.Int - rightUnion.Int) <= maxUlps);
        }
 /// <summary>
 ///   Reinterprets the memory contents of an integer as a floating point value
 /// </summary>
 /// <param name="value">Integer value whose memory contents to reinterpret</param>
 /// <returns>
 ///   The memory contents of the integer value interpreted as a floating point value
 /// </returns>
 public static float ReinterpretAsFloat(int value)
 {
     FloatIntUnion union = new FloatIntUnion();
     union.Int = value;
     return union.Float;
 }
 /// <summary>
 ///   Reinterprets the memory contents of a floating point value as an integer value
 /// </summary>
 /// <param name="value">
 ///   Floating point value whose memory contents to reinterpret
 /// </param>
 /// <returns>
 ///   The memory contents of the floating point value interpreted as an integer
 /// </returns>
 public static int ReinterpretAsInt(float value)
 {
     FloatIntUnion union = new FloatIntUnion();
     union.Float = value;
     return union.Int;
 }
Beispiel #21
0
        /// <summary>Compares two floating point _values for equality</summary>
        /// <param name="left">First floating point value to be compared</param>
        /// <param name="right">Second floating point value t be compared</param>
        /// <param name="maxUlps">
        ///   Maximum number of representable floating point _values that are allowed to
        ///   be between the left and the right floating point _values
        /// </param>
        /// <returns>True if both numbers are equal or close to being equal</returns>
        /// <remarks>
        ///   <para>
        ///     Floating point _values can only represent a finite subset of natural numbers.
        ///     For example, the _values 2.00000000 and 2.00000024 can be stored in a float,
        ///     but nothing inbetween them.
        ///   </para>
        ///   <para>
        ///     This comparison will count how many possible floating point _values are between
        ///     the left and the right number. If the number of possible _values between both
        ///     numbers is less than or equal to maxUlps, then the numbers are considered as
        ///     being equal.
        ///   </para>
        ///   <para>
        ///     Implementation partially follows the code outlined here:
        ///     http://www.anttirt.net/2007/08/19/proper-floating-point-comparisons/
        ///   </para>
        /// </remarks>
        public static bool AreAlmostEqualUlps(float left, float right, int maxUlps)
        {
            FloatIntUnion leftUnion = new FloatIntUnion();
            FloatIntUnion rightUnion = new FloatIntUnion();

            leftUnion.Float = left;
            rightUnion.Float = right;

            uint leftSignMask = (leftUnion.UInt >> 31);
            uint rightSignMask = (rightUnion.UInt >> 31);

            uint leftTemp = ((0x80000000 - leftUnion.UInt) & leftSignMask);
            leftUnion.UInt = leftTemp | (leftUnion.UInt & ~leftSignMask);

            uint rightTemp = ((0x80000000 - rightUnion.UInt) & rightSignMask);
            rightUnion.UInt = rightTemp | (rightUnion.UInt & ~rightSignMask);

            if (leftSignMask != rightSignMask) // Overflow possible, check each against zero
            {
                if (Math.Abs(leftUnion.Int) > maxUlps || Math.Abs(rightUnion.Int) > maxUlps)
                    return false;
            }

            // Either they have the same sign or both are very close to zero
            return Math.Abs(leftUnion.Int - rightUnion.Int) <= maxUlps;
        }