/// <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); }
/// <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); }
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); }
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); }
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; }
/// <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; }