Advertisement
FocusedWolf

DoubleExtensions

Jun 24th, 2015 (edited)
993
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 5.36 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3.  
  4. namespace MyProject.Extensions
  5. {
  6.     // Online post: http://pastebin.com/JFA1Bytm
  7.  
  8.     // SOURCE: https://github.com/mathnet/mathnet-numerics/blob/master/src/Numerics/Precision.cs
  9.     //         https://github.com/mathnet/mathnet-numerics/blob/master/src/Numerics/Precision.Equality.cs
  10.     //         http://referencesource.microsoft.com/#WindowsBase/Shared/MS/Internal/DoubleUtil.cs
  11.     //         http://stackoverflow.com/questions/2411392/double-epsilon-for-equality-greater-than-less-than-less-than-or-equal-to-gre
  12.  
  13.     public static class DoubleExtensions
  14.     {
  15.         #region Members
  16.  
  17.         public static double Coerce(this double value, List<double> pastValues, double tolerance = DoubleExtensions.NegativeMachineEpsilon * 10D)
  18.         {
  19.             foreach (var pastValue in pastValues)
  20.                 if (value.IsCloseTo(pastValue, tolerance))
  21.                     return pastValue;
  22.  
  23.             pastValues.Add(value);
  24.             return value;
  25.         }
  26.  
  27.         public static bool LessThan(this double value1, double value2)
  28.         {
  29.             return (value1 < value2) && !IsCloseTo(value1, value2);
  30.         }
  31.  
  32.         public static bool GreaterThan(this double value1, double value2)
  33.         {
  34.             return (value1 > value2) && !IsCloseTo(value1, value2);
  35.         }
  36.  
  37.         public static bool LessThanOrCloseTo(this double value1, double value2)
  38.         {
  39.             return (value1 < value2) || IsCloseTo(value1, value2);
  40.         }
  41.  
  42.         public static bool GreaterThanOrCloseTo(this double value1, double value2)
  43.         {
  44.             return (value1 > value2) || IsCloseTo(value1, value2);
  45.         }
  46.  
  47.         public static bool IsCloseTo(this double value1, double value2, double tolerance = DoubleExtensions.NegativeMachineEpsilon * 10D)
  48.         {
  49.             if (double.IsInfinity(value1) || double.IsInfinity(value2))
  50.                 return value1 == value2;
  51.  
  52.             if (double.IsNaN(value1) || double.IsNaN(value2))
  53.                 return false;
  54.  
  55.             var distance = Math.Abs(value1 - value2);
  56.             return distance <= tolerance;
  57.         }
  58.  
  59.         public static bool IsOne(this double value)
  60.         {
  61.             return Math.Abs(value - 1D) <= PositiveMachineEpsilon;
  62.         }
  63.  
  64.         public static bool IsZero(this double value)
  65.         {
  66.             return Math.Abs(value) <= PositiveMachineEpsilon;
  67.         }
  68.  
  69.         private static double MeasureNegativeMachineEpsilon()
  70.         {
  71.             var epsilon = 1D;
  72.  
  73.             do
  74.             {
  75.                 var nextEpsilon = epsilon / 2D;
  76.  
  77.                 if ((1D - nextEpsilon) == 1D) //if nextEpsilon is too small
  78.                     return epsilon;
  79.  
  80.                 epsilon = nextEpsilon;
  81.             }
  82.             while (true);
  83.         }
  84.  
  85.         private static double MeasurePositiveMachineEpsilon()
  86.         {
  87.             var epsilon = 1D;
  88.  
  89.             do
  90.             {
  91.                 var nextEpsilon = epsilon / 2D;
  92.  
  93.                 if ((1D + nextEpsilon) == 1D) //if nextEpsilon is too small
  94.                     return epsilon;
  95.  
  96.                 epsilon = nextEpsilon;
  97.             }
  98.             while (true);
  99.         }
  100.  
  101.         #endregion Members
  102.  
  103.         #region Fields
  104.  
  105.         /// <summary>
  106.         /// The smallest positive number that when SUBTRACTED from 1D yields a result different from 1D.
  107.         /// The value is derived from 2^(-53) = 1.1102230246251565e-16, where IEEE 754 binary64 &quot;double precision&quot; floating point numbers have a significand precision that utilize 53 bits.
  108.         ///
  109.         /// This number has the following properties:
  110.         ///     (1 - NegativeMachineEpsilon) &lt; 1 and
  111.         ///     (1 + NegativeMachineEpsilon) == 1
  112.         /// </summary>
  113.         public const double NegativeMachineEpsilon = 1.1102230246251565e-16D; //Math.Pow(2, -53);
  114.  
  115.         /// <summary>
  116.         /// The smallest positive number that when ADDED to 1D yields a result different from 1D.
  117.         /// The value is derived from 2 * 2^(-53) = 2.2204460492503131e-16, where IEEE 754 binary64 &quot;double precision&quot; floating point numbers have a significand precision that utilize 53 bits.
  118.         ///
  119.         /// This number has the following properties:
  120.         ///     (1 - PositiveDoublePrecision) &lt; 1 and
  121.         ///     (1 + PositiveDoublePrecision) &gt; 1
  122.         /// </summary>
  123.         public const double PositiveMachineEpsilon = 2D * NegativeMachineEpsilon;
  124.  
  125.         /// <summary>
  126.         /// The smallest positive number that when SUBTRACTED from 1D yields a result different from 1D.
  127.         ///
  128.         /// This number has the following properties:
  129.         ///     (1 - NegativeMachineEpsilon) &lt; 1 and
  130.         ///     (1 + NegativeMachineEpsilon) == 1
  131.         /// </summary>
  132.         public static readonly double MeasuredNegativeMachineEpsilon = MeasureNegativeMachineEpsilon();
  133.  
  134.         /// <summary>
  135.         /// The smallest positive number that when ADDED to 1D yields a result different from 1D.
  136.         ///
  137.         /// This number has the following properties:
  138.         ///     (1 - PositiveDoublePrecision) &lt; 1 and
  139.         ///     (1 + PositiveDoublePrecision) &gt; 1
  140.         /// </summary>
  141.         public static readonly double MeasuredPositiveMachineEpsilon = MeasurePositiveMachineEpsilon();
  142.  
  143.         #endregion Fields
  144.     }
  145. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement