summaryrefslogtreecommitdiff
path: root/src/mscorlib
diff options
context:
space:
mode:
authorEric Mellino <erme@microsoft.com>2017-07-19 10:17:04 -0700
committerGitHub <noreply@github.com>2017-07-19 10:17:04 -0700
commitfb5d0bcd7c3921834f53df32d8b86e90871838db (patch)
tree66415240b6e73499481ec511f1a179121a52a015 /src/mscorlib
parent4a89acc886703c047833ed9f705faa4857a14225 (diff)
parent09062805d6f2634be47068743a06aeb020df92ce (diff)
downloadcoreclr-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.cs4
-rw-r--r--src/mscorlib/src/System/Double.cs77
-rw-r--r--src/mscorlib/src/System/Single.cs62
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