From 748513675ede52cc30f3a45d53df680277e3bbde Mon Sep 17 00:00:00 2001 From: Christoph Ruegg Date: Mon, 28 Dec 2015 11:35:56 +0100 Subject: [PATCH] Precision: drop no longer needed PCL fallback --- src/Numerics/Precision.cs | 116 ++++---------------------------------- 1 file changed, 11 insertions(+), 105 deletions(-) diff --git a/src/Numerics/Precision.cs b/src/Numerics/Precision.cs index 9d4db21c..14fa9ac1 100644 --- a/src/Numerics/Precision.cs +++ b/src/Numerics/Precision.cs @@ -225,7 +225,7 @@ namespace MathNet.Numerics static long AsDirectionalInt64(double value) { // Convert in the normal way. - long result = DoubleToInt64Bits(value); + long result = BitConverter.DoubleToInt64Bits(value); // Now find out where we're at in the range // If the value is larger/equal to zero then we can just return the value @@ -279,7 +279,7 @@ namespace MathNet.Numerics // double < 0 --> long < 0, increasing in absolute magnitude as the double // gets closer to zero! // i.e. 0 - double.epsilon will give the largest long value! - long intValue = DoubleToInt64Bits(value); + long intValue = BitConverter.DoubleToInt64Bits(value); if (intValue < 0) { intValue -= count; @@ -297,7 +297,7 @@ namespace MathNet.Numerics // Note that not all long values can be translated into double values. There's a whole bunch of them // which return weird values like infinity and NaN - return Int64BitsToDouble(intValue); + return BitConverter.Int64BitsToDouble(intValue); } /// @@ -328,7 +328,7 @@ namespace MathNet.Numerics // double < 0 --> long < 0, increasing in absolute magnitude as the double // gets closer to zero! // i.e. 0 - double.epsilon will give the largest long value! - long intValue = DoubleToInt64Bits(value); + long intValue = BitConverter.DoubleToInt64Bits(value); // If the value is zero then we'd really like the value to be -0. So we'll make it -0 // and then everything else should work out. @@ -349,7 +349,7 @@ namespace MathNet.Numerics // Note that not all long values can be translated into double values. There's a whole bunch of them // which return weird values like infinity and NaN - return Int64BitsToDouble(intValue); + return BitConverter.Int64BitsToDouble(intValue); } /// @@ -473,56 +473,8 @@ namespace MathNet.Numerics // double < 0 --> long < 0, increasing in absolute magnitude as the double // gets closer to zero! // i.e. 0 - double.epsilon will give the largest long value! - long intValue = DoubleToInt64Bits(value); + long intValue = BitConverter.DoubleToInt64Bits(value); -#if PORTABLE - // We need to protect against over- and under-flow of the intValue when - // we start to add the ulpsDifference. - if (intValue < 0) - { - // Note that long.MinValue has the same bit pattern as - // -0.0. Therefore we're working in opposite direction (i.e. add if we want to - // go more negative and subtract if we want to go less negative) - var topRangeEnd = Math.Abs(long.MinValue - intValue) < maxNumbersBetween - // Got underflow, which can be fixed by splitting the calculation into two bits - // first get the remainder of the intValue after subtracting it from the long.MinValue - // and add that to the ulpsDifference. That way we'll turn positive without underflow - ? Int64BitsToDouble(maxNumbersBetween + (long.MinValue - intValue)) - // No problems here, move along. - : Int64BitsToDouble(intValue - maxNumbersBetween); - - var bottomRangeEnd = Math.Abs(intValue) < maxNumbersBetween - // Underflow, which means we'd have to go further than a long would allow us. - // Also we couldn't translate it back to a double, so we'll return -Double.MaxValue - ? -double.MaxValue - // intValue is negative. Adding the positive ulpsDifference means that it gets less negative. - // However due to the conversion way this means that the actual double value gets more negative :-S - : Int64BitsToDouble(intValue + maxNumbersBetween); - - return new Tuple(bottomRangeEnd, topRangeEnd); - } - else - { - // IntValue is positive - var topRangeEnd = long.MaxValue - intValue < maxNumbersBetween - // Overflow, which means we'd have to go further than a long would allow us. - // Also we couldn't translate it back to a double, so we'll return Double.MaxValue - ? double.MaxValue - // No troubles here - : Int64BitsToDouble(intValue + maxNumbersBetween); - - // Check the bottom range end for underflows - var bottomRangeEnd = intValue > maxNumbersBetween - // No problems here. IntValue is larger than ulpsDifference so we'll end up with a - // positive number. - ? Int64BitsToDouble(intValue - maxNumbersBetween) - // Int value is bigger than zero but smaller than the ulpsDifference. So we'll need to deal with - // the reversal at the negative end - : Int64BitsToDouble(long.MinValue + (maxNumbersBetween - intValue)); - - return new Tuple(bottomRangeEnd, topRangeEnd); - } -#else // We need to protect against over- and under-flow of the intValue when // we start to add the ulpsDifference. if (intValue < 0) @@ -569,7 +521,6 @@ namespace MathNet.Numerics return new Tuple(bottomRangeEnd, topRangeEnd); } -#endif } /// @@ -639,7 +590,7 @@ namespace MathNet.Numerics // so return the ulps counts for the difference. if (value.Equals(0)) { - var v = DoubleToInt64Bits(relativeDifference); + var v = BitConverter.DoubleToInt64Bits(relativeDifference); return new Tuple(v, v); } @@ -713,17 +664,17 @@ namespace MathNet.Numerics return double.NaN; } - long signed64 = DoubleToInt64Bits(value); + long signed64 = BitConverter.DoubleToInt64Bits(value); if (signed64 == 0) { signed64++; - return Int64BitsToDouble(signed64) - value; + return BitConverter.Int64BitsToDouble(signed64) - value; } if (signed64-- < 0) { - return Int64BitsToDouble(signed64) - value; + return BitConverter.Int64BitsToDouble(signed64) - value; } - return value - Int64BitsToDouble(signed64); + return value - BitConverter.Int64BitsToDouble(signed64); } /// @@ -779,17 +730,6 @@ namespace MathNet.Numerics return 2 * EpsilonOf(value); } - /// - /// Converts a float value to a bit array stored in an int. - /// - /// The value to convert. - /// The bit array. - static int FloatToInt32Bits(float value) - { - return SingleToInt32Bits(value); - } - - /// /// Calculates the actual (negative) double precision machine epsilon - the smallest number that can be subtracted from 1, yielding a results different than 1. /// This is also known as unit roundoff error. According to the definition of Prof. Demmel. @@ -830,28 +770,6 @@ namespace MathNet.Numerics #endif } - [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")] - static long DoubleToInt64Bits(double value) - { -#if PORTABLE - var union = new DoubleLongUnion { Double = value }; - return union.Int64; -#else - return BitConverter.DoubleToInt64Bits(value); -#endif - } - - [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")] - static double Int64BitsToDouble(long value) - { -#if PORTABLE - var union = new DoubleLongUnion { Int64 = value }; - return union.Double; -#else - return BitConverter.Int64BitsToDouble(value); -#endif - } - static int SingleToInt32Bits(float value) { var union = new SingleIntUnion { Single = value }; @@ -864,18 +782,6 @@ namespace MathNet.Numerics return union.Single; } -#if PORTABLE - [StructLayout(LayoutKind.Explicit)] - struct DoubleLongUnion - { - [FieldOffset(0)] - public double Double; - - [FieldOffset(0)] - public long Int64; - } -#endif - [StructLayout(LayoutKind.Explicit)] struct SingleIntUnion {