diff options
author | Eric Mellino <erme@microsoft.com> | 2017-07-19 10:17:04 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-07-19 10:17:04 -0700 |
commit | fb5d0bcd7c3921834f53df32d8b86e90871838db (patch) | |
tree | 66415240b6e73499481ec511f1a179121a52a015 /src/mscorlib | |
parent | 4a89acc886703c047833ed9f705faa4857a14225 (diff) | |
parent | 09062805d6f2634be47068743a06aeb020df92ce (diff) | |
download | coreclr-fb5d0bcd7c3921834f53df32d8b86e90871838db.tar.gz coreclr-fb5d0bcd7c3921834f53df32d8b86e90871838db.tar.bz2 coreclr-fb5d0bcd7c3921834f53df32d8b86e90871838db.zip |
Merge pull request #12755 from tannergooding/classify
Floating-Point Classification APIs
Diffstat (limited to 'src/mscorlib')
-rw-r--r-- | src/mscorlib/shared/System/BitConverter.cs | 4 | ||||
-rw-r--r-- | src/mscorlib/src/System/Double.cs | 77 | ||||
-rw-r--r-- | src/mscorlib/src/System/Single.cs | 62 |
3 files changed, 111 insertions, 32 deletions
diff --git a/src/mscorlib/shared/System/BitConverter.cs b/src/mscorlib/shared/System/BitConverter.cs index 8c23102dec..e19229dd37 100644 --- a/src/mscorlib/shared/System/BitConverter.cs +++ b/src/mscorlib/shared/System/BitConverter.cs @@ -298,21 +298,25 @@ namespace System return value[startIndex] != 0; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static unsafe long DoubleToInt64Bits(double value) { return *((long*)&value); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static unsafe double Int64BitsToDouble(long value) { return *((double*)&value); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static unsafe int SingleToInt32Bits(float value) { return *((int*)&value); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static unsafe float Int32BitsToSingle(int value) { return *((float*)&value); diff --git a/src/mscorlib/src/System/Double.cs b/src/mscorlib/src/System/Double.cs index b64bb72ed2..ee5ffa0ccf 100644 --- a/src/mscorlib/src/System/Double.cs +++ b/src/mscorlib/src/System/Double.cs @@ -44,56 +44,85 @@ namespace System internal static double NegativeZero = BitConverter.Int64BitsToDouble(unchecked((long)0x8000000000000000)); + /// <summary>Determines whether the specified value is finite (zero, subnormal, or normal).</summary> [Pure] [System.Runtime.Versioning.NonVersionable] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe static bool IsFinite(double d) + { + var bits = BitConverter.DoubleToInt64Bits(d); + return (bits & 0x7FFFFFFFFFFFFFFF) < 0x7FF0000000000000; + } + + /// <summary>Determines whether the specified value is infinite.</summary> + [Pure] + [System.Runtime.Versioning.NonVersionable] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static bool IsInfinity(double d) { - return (*(long*)(&d) & 0x7FFFFFFFFFFFFFFF) == 0x7FF0000000000000; + var bits = BitConverter.DoubleToInt64Bits(d); + return (bits & 0x7FFFFFFFFFFFFFFF) == 0x7FF0000000000000; } + /// <summary>Determines whether the specified value is NaN.</summary> [Pure] [System.Runtime.Versioning.NonVersionable] - public static bool IsPositiveInfinity(double d) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe static bool IsNaN(double d) { - //Jit will generate inlineable code with this - if (d == double.PositiveInfinity) - { - return true; - } - else - { - return false; - } + var bits = BitConverter.DoubleToInt64Bits(d); + return (bits & 0x7FFFFFFFFFFFFFFF) > 0x7FF0000000000000; } + /// <summary>Determines whether the specified value is negative.</summary> [Pure] [System.Runtime.Versioning.NonVersionable] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe static bool IsNegative(double d) + { + var bits = unchecked((ulong)BitConverter.DoubleToInt64Bits(d)); + return (bits & 0x8000000000000000) == 0x8000000000000000; + } + + /// <summary>Determines whether the specified value is negative infinity.</summary> + [Pure] + [System.Runtime.Versioning.NonVersionable] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool IsNegativeInfinity(double d) { - //Jit will generate inlineable code with this - if (d == double.NegativeInfinity) - { - return true; - } - else - { - return false; - } + return (d == double.NegativeInfinity); } + /// <summary>Determines whether the specified value is normal.</summary> [Pure] - internal unsafe static bool IsNegative(double d) + [System.Runtime.Versioning.NonVersionable] + // This is probably not worth inlining, it has branches and should be rarely called + public unsafe static bool IsNormal(double d) { - return (*(UInt64*)(&d) & 0x8000000000000000) == 0x8000000000000000; + var bits = BitConverter.DoubleToInt64Bits(d); + bits &= 0x7FFFFFFFFFFFFFFF; + return (bits < 0x7FF0000000000000) && (bits != 0) && ((bits & 0x7FF0000000000000) != 0); } + /// <summary>Determines whether the specified value is positive infinity.</summary> [Pure] [System.Runtime.Versioning.NonVersionable] - public unsafe static bool IsNaN(double d) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool IsPositiveInfinity(double d) { - return (*(UInt64*)(&d) & 0x7FFFFFFFFFFFFFFFL) > 0x7FF0000000000000L; + return (d == double.PositiveInfinity); } + /// <summary>Determines whether the specified value is subnormal.</summary> + [Pure] + [System.Runtime.Versioning.NonVersionable] + // This is probably not worth inlining, it has branches and should be rarely called + public unsafe static bool IsSubnormal(double d) + { + var bits = BitConverter.DoubleToInt64Bits(d); + bits &= 0x7FFFFFFFFFFFFFFF; + return (bits < 0x7FF0000000000000) && (bits != 0) && ((bits & 0x7FF0000000000000) == 0); + } // Compares this object to another object, returning an instance of System.Relation. // Null is considered less than any instance. diff --git a/src/mscorlib/src/System/Single.cs b/src/mscorlib/src/System/Single.cs index c94e673c26..2bdc2a9696 100644 --- a/src/mscorlib/src/System/Single.cs +++ b/src/mscorlib/src/System/Single.cs @@ -40,38 +40,84 @@ namespace System internal static float NegativeZero = BitConverter.Int32BitsToSingle(unchecked((int)0x80000000)); + /// <summary>Determines whether the specified value is finite (zero, subnormal, or normal).</summary> [Pure] [System.Runtime.Versioning.NonVersionable] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool IsFinite(float f) + { + var bits = BitConverter.SingleToInt32Bits(f); + return (bits & 0x7FFFFFFF) < 0x7F800000; + } + + /// <summary>Determines whether the specified value is infinite.</summary> + [Pure] + [System.Runtime.Versioning.NonVersionable] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static bool IsInfinity(float f) { - return (*(int*)(&f) & 0x7FFFFFFF) == 0x7F800000; + var bits = BitConverter.SingleToInt32Bits(f); + return (bits & 0x7FFFFFFF) == 0x7F800000; } + /// <summary>Determines whether the specified value is NaN.</summary> [Pure] [System.Runtime.Versioning.NonVersionable] - public unsafe static bool IsPositiveInfinity(float f) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe static bool IsNaN(float f) + { + var bits = BitConverter.SingleToInt32Bits(f); + return (bits & 0x7FFFFFFF) > 0x7F800000; + } + + /// <summary>Determines whether the specified value is negative.</summary> + [Pure] + [System.Runtime.Versioning.NonVersionable] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe static bool IsNegative(float f) { - return *(int*)(&f) == 0x7F800000; + var bits = unchecked((uint)BitConverter.SingleToInt32Bits(f)); + return (bits & 0x80000000) == 0x80000000; } + /// <summary>Determines whether the specified value is negative infinity.</summary> [Pure] [System.Runtime.Versioning.NonVersionable] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static bool IsNegativeInfinity(float f) { - return *(int*)(&f) == unchecked((int)0xFF800000); + return (f == float.NegativeInfinity); } + /// <summary>Determines whether the specified value is normal.</summary> [Pure] [System.Runtime.Versioning.NonVersionable] - public unsafe static bool IsNaN(float f) + // This is probably not worth inlining, it has branches and should be rarely called + public unsafe static bool IsNormal(float f) + { + var bits = BitConverter.SingleToInt32Bits(f); + bits &= 0x7FFFFFFF; + return (bits < 0x7F800000) && (bits != 0) && ((bits & 0x7F800000) != 0); + } + + /// <summary>Determines whether the specified value is positive infinity.</summary> + [Pure] + [System.Runtime.Versioning.NonVersionable] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe static bool IsPositiveInfinity(float f) { - return (*(int*)(&f) & 0x7FFFFFFF) > 0x7F800000; + return (f == float.PositiveInfinity); } + /// <summary>Determines whether the specified value is subnormal.</summary> [Pure] - internal unsafe static bool IsNegative(float f) + [System.Runtime.Versioning.NonVersionable] + // This is probably not worth inlining, it has branches and should be rarely called + public unsafe static bool IsSubnormal(float f) { - return (*(uint*)(&f) & 0x80000000) == 0x80000000; + var bits = BitConverter.SingleToInt32Bits(f); + bits &= 0x7FFFFFFF; + return (bits < 0x7F800000) && (bits != 0) && ((bits & 0x7F800000) == 0); } // Compares this object to another object, returning an integer that |