| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148 |
- /*************************************************************************************
- Extended WPF Toolkit
- Copyright (C) 2007-2013 Xceed Software Inc.
- This program is provided to you under the terms of the Microsoft Public
- License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license
- For more features, controls, and fast professional support,
- pick up the Plus Edition at http://xceed.com/wpf_toolkit
- Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids
- ***********************************************************************************/
- namespace Standard
- {
- using System;
- using System.Diagnostics.CodeAnalysis;
- /// <summary>
- /// DoubleUtil uses fixed eps to provide fuzzy comparison functionality for doubles.
- /// Note that FP noise is a big problem and using any of these compare
- /// methods is not a complete solution, but rather the way to reduce
- /// the probability of repeating unnecessary work.
- /// </summary>
- internal static class DoubleUtilities
- {
- /// <summary>
- /// Epsilon - more or less random, more or less small number.
- /// </summary>
- private const double Epsilon = 0.00000153;
- /// <summary>
- /// AreClose returns whether or not two doubles are "close". That is, whether or
- /// not they are within epsilon of each other.
- /// There are plenty of ways for this to return false even for numbers which
- /// are theoretically identical, so no code calling this should fail to work if this
- /// returns false.
- /// </summary>
- /// <param name="value1">The first double to compare.</param>
- /// <param name="value2">The second double to compare.</param>
- /// <returns>The result of the AreClose comparision.</returns>
- [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
- public static bool AreClose(double value1, double value2)
- {
- if (value1 == value2)
- {
- return true;
- }
- double delta = value1 - value2;
- return (delta < Epsilon) && (delta > -Epsilon);
- }
- /// <summary>
- /// LessThan returns whether or not the first double is less than the second double.
- /// That is, whether or not the first is strictly less than *and* not within epsilon of
- /// the other number.
- /// There are plenty of ways for this to return false even for numbers which
- /// are theoretically identical, so no code calling this should fail to work if this
- /// returns false.
- /// </summary>
- /// <param name="value1">The first double to compare.</param>
- /// <param name="value2">The second double to compare.</param>
- /// <returns>The result of the LessThan comparision.</returns>
- [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
- public static bool LessThan(double value1, double value2)
- {
- return (value1 < value2) && !AreClose(value1, value2);
- }
- /// <summary>
- /// GreaterThan returns whether or not the first double is greater than the second double.
- /// That is, whether or not the first is strictly greater than *and* not within epsilon of
- /// the other number.
- /// There are plenty of ways for this to return false even for numbers which
- /// are theoretically identical, so no code calling this should fail to work if this
- /// returns false.
- /// </summary>
- /// <param name="value1">The first double to compare.</param>
- /// <param name="value2">The second double to compare.</param>
- /// <returns>The result of the GreaterThan comparision.</returns>
- [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
- public static bool GreaterThan(double value1, double value2)
- {
- return (value1 > value2) && !AreClose(value1, value2);
- }
- /// <summary>
- /// LessThanOrClose returns whether or not the first double is less than or close to
- /// the second double. That is, whether or not the first is strictly less than or within
- /// epsilon of the other number.
- /// There are plenty of ways for this to return false even for numbers which
- /// are theoretically identical, so no code calling this should fail to work if this
- /// returns false.
- /// </summary>
- /// <param name="value1">The first double to compare.</param>
- /// <param name="value2">The second double to compare.</param>
- /// <returns>The result of the LessThanOrClose comparision.</returns>
- [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
- public static bool LessThanOrClose(double value1, double value2)
- {
- return (value1 < value2) || AreClose(value1, value2);
- }
- /// <summary>
- /// GreaterThanOrClose returns whether or not the first double is greater than or close to
- /// the second double. That is, whether or not the first is strictly greater than or within
- /// epsilon of the other number.
- /// There are plenty of ways for this to return false even for numbers which
- /// are theoretically identical, so no code calling this should fail to work if this
- /// returns false.
- /// </summary>
- /// <param name="value1">The first double to compare.</param>
- /// <param name="value2">The second double to compare.</param>
- /// <returns>The result of the GreaterThanOrClose comparision.</returns>
- [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
- public static bool GreaterThanOrClose(double value1, double value2)
- {
- return (value1 > value2) || AreClose(value1, value2);
- }
- /// <summary>
- /// Test to see if a double is a finite number (is not NaN or Infinity).
- /// </summary>
- /// <param name='value'>The value to test.</param>
- /// <returns>Whether or not the value is a finite number.</returns>
- [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
- public static bool IsFinite(double value)
- {
- return !double.IsNaN(value) && !double.IsInfinity(value);
- }
- /// <summary>
- /// Test to see if a double a valid size value (is finite and > 0).
- /// </summary>
- /// <param name='value'>The value to test.</param>
- /// <returns>Whether or not the value is a valid size value.</returns>
- [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
- public static bool IsValidSize(double value)
- {
- return IsFinite(value) && GreaterThanOrClose(value, 0);
- }
- }
- }
|