<PackageReference Include="NUnit" Version="3.10.1" />

FloatingPointNumerics

public class FloatingPointNumerics
Helper routines for working with floating point numbers
using System; using System.Runtime.InteropServices; namespace NUnit.Framework.Constraints { public class FloatingPointNumerics { [StructLayout(LayoutKind.Explicit)] private struct FloatIntUnion { [FieldOffset(0)] public float Float; [FieldOffset(0)] public int Int; [FieldOffset(0)] public uint UInt; } [StructLayout(LayoutKind.Explicit)] private struct DoubleLongUnion { [FieldOffset(0)] public double Double; [FieldOffset(0)] public long Long; [FieldOffset(0)] public ulong ULong; } 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 = (uint)((-2147483648 - (int)floatIntUnion.UInt) & (int)num); floatIntUnion.UInt = (num3 | (floatIntUnion.UInt & ~num)); uint num4 = (uint)((-2147483648 - (int)floatIntUnion2.UInt) & (int)num2); floatIntUnion2.UInt = (num4 | (floatIntUnion2.UInt & ~num2)); if (num != num2 && (Math.Abs(floatIntUnion.Int) > maxUlps || Math.Abs(floatIntUnion2.Int) > maxUlps)) return false; return Math.Abs(floatIntUnion.Int - floatIntUnion2.Int) <= maxUlps; } public static bool AreAlmostEqualUlps(double left, double right, long maxUlps) { DoubleLongUnion doubleLongUnion = default(DoubleLongUnion); DoubleLongUnion doubleLongUnion2 = default(DoubleLongUnion); doubleLongUnion.Double = left; doubleLongUnion2.Double = right; ulong num = doubleLongUnion.ULong >> 63; ulong num2 = doubleLongUnion2.ULong >> 63; ulong num3 = (ulong)((-9223372036854775808 - (long)doubleLongUnion.ULong) & (long)num); doubleLongUnion.ULong = (num3 | (doubleLongUnion.ULong & ~num)); ulong num4 = (ulong)((-9223372036854775808 - (long)doubleLongUnion2.ULong) & (long)num2); doubleLongUnion2.ULong = (num4 | (doubleLongUnion2.ULong & ~num2)); if (num != num2 && (Math.Abs(doubleLongUnion.Long) > maxUlps || Math.Abs(doubleLongUnion2.Long) > maxUlps)) return false; return Math.Abs(doubleLongUnion.Long - doubleLongUnion2.Long) <= maxUlps; } public static int ReinterpretAsInt(float value) { FloatIntUnion floatIntUnion = default(FloatIntUnion); floatIntUnion.Float = value; return floatIntUnion.Int; } public static long ReinterpretAsLong(double value) { DoubleLongUnion doubleLongUnion = default(DoubleLongUnion); doubleLongUnion.Double = value; return doubleLongUnion.Long; } public static float ReinterpretAsFloat(int value) { FloatIntUnion floatIntUnion = default(FloatIntUnion); floatIntUnion.Int = value; return floatIntUnion.Float; } public static double ReinterpretAsDouble(long value) { DoubleLongUnion doubleLongUnion = default(DoubleLongUnion); doubleLongUnion.Long = value; return doubleLongUnion.Double; } private FloatingPointNumerics() { } } }