Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.Collections.Generic;
- namespace MyProject.Extensions
- {
- // Online post: http://pastebin.com/JFA1Bytm
- // SOURCE: https://github.com/mathnet/mathnet-numerics/blob/master/src/Numerics/Precision.cs
- // https://github.com/mathnet/mathnet-numerics/blob/master/src/Numerics/Precision.Equality.cs
- // http://referencesource.microsoft.com/#WindowsBase/Shared/MS/Internal/DoubleUtil.cs
- // http://stackoverflow.com/questions/2411392/double-epsilon-for-equality-greater-than-less-than-less-than-or-equal-to-gre
- public static class DoubleExtensions
- {
- #region Members
- public static double Coerce(this double value, List<double> pastValues, double tolerance = DoubleExtensions.NegativeMachineEpsilon * 10D)
- {
- foreach (var pastValue in pastValues)
- if (value.IsCloseTo(pastValue, tolerance))
- return pastValue;
- pastValues.Add(value);
- return value;
- }
- public static bool LessThan(this double value1, double value2)
- {
- return (value1 < value2) && !IsCloseTo(value1, value2);
- }
- public static bool GreaterThan(this double value1, double value2)
- {
- return (value1 > value2) && !IsCloseTo(value1, value2);
- }
- public static bool LessThanOrCloseTo(this double value1, double value2)
- {
- return (value1 < value2) || IsCloseTo(value1, value2);
- }
- public static bool GreaterThanOrCloseTo(this double value1, double value2)
- {
- return (value1 > value2) || IsCloseTo(value1, value2);
- }
- public static bool IsCloseTo(this double value1, double value2, double tolerance = DoubleExtensions.NegativeMachineEpsilon * 10D)
- {
- if (double.IsInfinity(value1) || double.IsInfinity(value2))
- return value1 == value2;
- if (double.IsNaN(value1) || double.IsNaN(value2))
- return false;
- var distance = Math.Abs(value1 - value2);
- return distance <= tolerance;
- }
- public static bool IsOne(this double value)
- {
- return Math.Abs(value - 1D) <= PositiveMachineEpsilon;
- }
- public static bool IsZero(this double value)
- {
- return Math.Abs(value) <= PositiveMachineEpsilon;
- }
- private static double MeasureNegativeMachineEpsilon()
- {
- var epsilon = 1D;
- do
- {
- var nextEpsilon = epsilon / 2D;
- if ((1D - nextEpsilon) == 1D) //if nextEpsilon is too small
- return epsilon;
- epsilon = nextEpsilon;
- }
- while (true);
- }
- private static double MeasurePositiveMachineEpsilon()
- {
- var epsilon = 1D;
- do
- {
- var nextEpsilon = epsilon / 2D;
- if ((1D + nextEpsilon) == 1D) //if nextEpsilon is too small
- return epsilon;
- epsilon = nextEpsilon;
- }
- while (true);
- }
- #endregion Members
- #region Fields
- /// <summary>
- /// The smallest positive number that when SUBTRACTED from 1D yields a result different from 1D.
- /// The value is derived from 2^(-53) = 1.1102230246251565e-16, where IEEE 754 binary64 "double precision" floating point numbers have a significand precision that utilize 53 bits.
- ///
- /// This number has the following properties:
- /// (1 - NegativeMachineEpsilon) < 1 and
- /// (1 + NegativeMachineEpsilon) == 1
- /// </summary>
- public const double NegativeMachineEpsilon = 1.1102230246251565e-16D; //Math.Pow(2, -53);
- /// <summary>
- /// The smallest positive number that when ADDED to 1D yields a result different from 1D.
- /// The value is derived from 2 * 2^(-53) = 2.2204460492503131e-16, where IEEE 754 binary64 "double precision" floating point numbers have a significand precision that utilize 53 bits.
- ///
- /// This number has the following properties:
- /// (1 - PositiveDoublePrecision) < 1 and
- /// (1 + PositiveDoublePrecision) > 1
- /// </summary>
- public const double PositiveMachineEpsilon = 2D * NegativeMachineEpsilon;
- /// <summary>
- /// The smallest positive number that when SUBTRACTED from 1D yields a result different from 1D.
- ///
- /// This number has the following properties:
- /// (1 - NegativeMachineEpsilon) < 1 and
- /// (1 + NegativeMachineEpsilon) == 1
- /// </summary>
- public static readonly double MeasuredNegativeMachineEpsilon = MeasureNegativeMachineEpsilon();
- /// <summary>
- /// The smallest positive number that when ADDED to 1D yields a result different from 1D.
- ///
- /// This number has the following properties:
- /// (1 - PositiveDoublePrecision) < 1 and
- /// (1 + PositiveDoublePrecision) > 1
- /// </summary>
- public static readonly double MeasuredPositiveMachineEpsilon = MeasurePositiveMachineEpsilon();
- #endregion Fields
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement