Code:
/ Dotnetfx_Win7_3.5.1 / Dotnetfx_Win7_3.5.1 / 3.5.1 / DEVDIV / depot / DevDiv / releases / Orcas / NetFXw7 / wpf / src / Shared / MS / Internal / DoubleUtil.cs / 1 / DoubleUtil.cs
//----------------------------------------------------------------------------
//
// Copyright (C) Microsoft Corporation. All rights reserved.
//
// File: DoubleUtil.cs
//
// Description: This file contains the implementation of DoubleUtil, which
// provides "fuzzy" comparison functionality for doubles and
// double-based classes and structs in our code.
//
// History:
// 04/28/2003 : adsmith - Created
// 05/20/2003 : adsmith - Moved it to Shared, so Base, Core and Framework can all share.
//
//---------------------------------------------------------------------------
using System;
using System.Windows;
using System.Runtime.InteropServices;
#if WINDOWS_BASE
using MS.Internal.WindowsBase;
#elif PRESENTATION_CORE
using MS.Internal.PresentationCore;
#elif PRESENTATIONFRAMEWORK
using MS.Internal.PresentationFramework;
#elif DRT
using MS.Internal.Drt;
#else
#error Attempt to use FriendAccessAllowedAttribute from an unknown assembly.
using MS.Internal.YourAssemblyName;
#endif
namespace MS.Internal
{
[FriendAccessAllowed]
internal static class DoubleUtil
{
// Const values come from sdk\inc\crt\float.h
internal const double DBL_EPSILON = 2.2204460492503131e-016; /* smallest such that 1.0+DBL_EPSILON != 1.0 */
internal const float FLT_MIN = 1.175494351e-38F; /* Number close to zero, where float.MinValue is -float.MaxValue */
///
/// AreClose - Returns whether or not two doubles are "close". That is, whether or
/// not they are within epsilon of each other. Note that this epsilon is proportional
/// to the numbers themselves to that AreClose survives scalar multiplication.
/// 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. This is important enough to repeat:
/// NB: NO CODE CALLING THIS FUNCTION SHOULD DEPEND ON ACCURATE RESULTS - this should be
/// used for optimizations *only*.
///
///
/// bool - the result of the AreClose comparision.
///
/// The first double to compare.
/// The second double to compare.
public static bool AreClose(double value1, double value2)
{
//in case they are Infinities (then epsilon check does not work)
if(value1 == value2) return true;
// This computes (|value1-value2| / (|value1| + |value2| + 10.0)) < DBL_EPSILON
double eps = (Math.Abs(value1) + Math.Abs(value2) + 10.0) * DBL_EPSILON;
double delta = value1 - value2;
return(-eps < delta) && (eps > delta);
}
///
/// 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. Note that this epsilon is proportional to the numbers themselves
/// to that AreClose survives scalar multiplication. Note,
/// 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. This is important enough to repeat:
/// NB: NO CODE CALLING THIS FUNCTION SHOULD DEPEND ON ACCURATE RESULTS - this should be
/// used for optimizations *only*.
///
///
/// bool - the result of the LessThan comparision.
///
/// The first double to compare.
/// The second double to compare.
public static bool LessThan(double value1, double value2)
{
return (value1 < value2) && !AreClose(value1, value2);
}
///
/// 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. Note that this epsilon is proportional to the numbers themselves
/// to that AreClose survives scalar multiplication. Note,
/// 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. This is important enough to repeat:
/// NB: NO CODE CALLING THIS FUNCTION SHOULD DEPEND ON ACCURATE RESULTS - this should be
/// used for optimizations *only*.
///
///
/// bool - the result of the GreaterThan comparision.
///
/// The first double to compare.
/// The second double to compare.
public static bool GreaterThan(double value1, double value2)
{
return (value1 > value2) && !AreClose(value1, value2);
}
///
/// 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. Note that this epsilon is proportional to the numbers
/// themselves to that AreClose survives scalar multiplication. Note,
/// 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. This is important enough to repeat:
/// NB: NO CODE CALLING THIS FUNCTION SHOULD DEPEND ON ACCURATE RESULTS - this should be
/// used for optimizations *only*.
///
///
/// bool - the result of the LessThanOrClose comparision.
///
/// The first double to compare.
/// The second double to compare.
public static bool LessThanOrClose(double value1, double value2)
{
return (value1 < value2) || AreClose(value1, value2);
}
///
/// 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. Note that this epsilon is proportional to the numbers
/// themselves to that AreClose survives scalar multiplication. Note,
/// 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. This is important enough to repeat:
/// NB: NO CODE CALLING THIS FUNCTION SHOULD DEPEND ON ACCURATE RESULTS - this should be
/// used for optimizations *only*.
///
///
/// bool - the result of the GreaterThanOrClose comparision.
///
/// The first double to compare.
/// The second double to compare.
public static bool GreaterThanOrClose(double value1, double value2)
{
return (value1 > value2) || AreClose(value1, value2);
}
///
/// IsOne - Returns whether or not the double is "close" to 1. Same as AreClose(double, 1),
/// but this is faster.
///
///
/// bool - the result of the AreClose comparision.
///
/// The double to compare to 1.
public static bool IsOne(double value)
{
return Math.Abs(value-1.0) < 10.0 * DBL_EPSILON;
}
///
/// IsZero - Returns whether or not the double is "close" to 0. Same as AreClose(double, 0),
/// but this is faster.
///
///
/// bool - the result of the AreClose comparision.
///
/// The double to compare to 0.
public static bool IsZero(double value)
{
return Math.Abs(value) < 10.0 * DBL_EPSILON;
}
// The Point, Size, Rect and Matrix class have moved to WinCorLib. However, we provide
// internal AreClose methods for our own use here.
///
/// Compares two points for fuzzy equality. This function
/// helps compensate for the fact that double values can
/// acquire error when operated upon
///
/// The first point to compare
/// The second point to compare
/// Whether or not the two points are equal
public static bool AreClose(Point point1, Point point2)
{
return DoubleUtil.AreClose(point1.X, point2.X) &&
DoubleUtil.AreClose(point1.Y, point2.Y);
}
///
/// Compares two Size instances for fuzzy equality. This function
/// helps compensate for the fact that double values can
/// acquire error when operated upon
///
/// The first size to compare
/// The second size to compare
/// Whether or not the two Size instances are equal
public static bool AreClose(Size size1, Size size2)
{
return DoubleUtil.AreClose(size1.Width, size2.Width) &&
DoubleUtil.AreClose(size1.Height, size2.Height);
}
///
/// Compares two Vector instances for fuzzy equality. This function
/// helps compensate for the fact that double values can
/// acquire error when operated upon
///
/// The first Vector to compare
/// The second Vector to compare
/// Whether or not the two Vector instances are equal
public static bool AreClose(System.Windows.Vector vector1, System.Windows.Vector vector2)
{
return DoubleUtil.AreClose(vector1.X, vector2.X) &&
DoubleUtil.AreClose(vector1.Y, vector2.Y);
}
///
/// Compares two rectangles for fuzzy equality. This function
/// helps compensate for the fact that double values can
/// acquire error when operated upon
///
/// The first rectangle to compare
/// The second rectangle to compare
/// Whether or not the two rectangles are equal
public static bool AreClose(Rect rect1, Rect rect2)
{
// If they're both empty, don't bother with the double logic.
if (rect1.IsEmpty)
{
return rect2.IsEmpty;
}
// At this point, rect1 isn't empty, so the first thing we can test is
// rect2.IsEmpty, followed by property-wise compares.
return (!rect2.IsEmpty) &&
DoubleUtil.AreClose(rect1.X, rect2.X) &&
DoubleUtil.AreClose(rect1.Y, rect2.Y) &&
DoubleUtil.AreClose(rect1.Height, rect2.Height) &&
DoubleUtil.AreClose(rect1.Width, rect2.Width);
}
///
///
///
///
///
public static bool IsBetweenZeroAndOne(double val)
{
return (GreaterThanOrClose(val, 0) && LessThanOrClose(val, 1));
}
///
///
///
///
///
public static int DoubleToInt(double val)
{
return (0 < val) ? (int)(val + 0.5) : (int)(val - 0.5);
}
///
/// rectHasNaN - this returns true if this rect has X, Y , Height or Width as NaN.
///
/// The rectangle to test
/// returns whether the Rect has NaN
public static bool RectHasNaN(Rect r)
{
if ( DoubleUtil.IsNaN(r.X)
|| DoubleUtil.IsNaN(r.Y)
|| DoubleUtil.IsNaN(r.Height)
|| DoubleUtil.IsNaN(r.Width) )
{
return true;
}
return false;
}
#if !PBTCOMPILER
[StructLayout(LayoutKind.Explicit)]
private struct NanUnion
{
[FieldOffset(0)] internal double DoubleValue;
[FieldOffset(0)] internal UInt64 UintValue;
}
// The standard CLR double.IsNaN() function is approximately 100 times slower than our own wrapper,
// so please make sure to use DoubleUtil.IsNaN() in performance sensitive code.
// PS item that tracks the CLR improvement is DevDiv Schedule : 26916.
// IEEE 754 : If the argument is any value in the range 0x7ff0000000000001L through 0x7fffffffffffffffL
// or in the range 0xfff0000000000001L through 0xffffffffffffffffL, the result will be NaN.
public static bool IsNaN(double value)
{
NanUnion t = new NanUnion();
t.DoubleValue = value;
UInt64 exp = t.UintValue & 0xfff0000000000000;
UInt64 man = t.UintValue & 0x000fffffffffffff;
return (exp == 0x7ff0000000000000 || exp == 0xfff0000000000000) && (man != 0);
}
#endif
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
//----------------------------------------------------------------------------
//
// Copyright (C) Microsoft Corporation. All rights reserved.
//
// File: DoubleUtil.cs
//
// Description: This file contains the implementation of DoubleUtil, which
// provides "fuzzy" comparison functionality for doubles and
// double-based classes and structs in our code.
//
// History:
// 04/28/2003 : adsmith - Created
// 05/20/2003 : adsmith - Moved it to Shared, so Base, Core and Framework can all share.
//
//---------------------------------------------------------------------------
using System;
using System.Windows;
using System.Runtime.InteropServices;
#if WINDOWS_BASE
using MS.Internal.WindowsBase;
#elif PRESENTATION_CORE
using MS.Internal.PresentationCore;
#elif PRESENTATIONFRAMEWORK
using MS.Internal.PresentationFramework;
#elif DRT
using MS.Internal.Drt;
#else
#error Attempt to use FriendAccessAllowedAttribute from an unknown assembly.
using MS.Internal.YourAssemblyName;
#endif
namespace MS.Internal
{
[FriendAccessAllowed]
internal static class DoubleUtil
{
// Const values come from sdk\inc\crt\float.h
internal const double DBL_EPSILON = 2.2204460492503131e-016; /* smallest such that 1.0+DBL_EPSILON != 1.0 */
internal const float FLT_MIN = 1.175494351e-38F; /* Number close to zero, where float.MinValue is -float.MaxValue */
///
/// AreClose - Returns whether or not two doubles are "close". That is, whether or
/// not they are within epsilon of each other. Note that this epsilon is proportional
/// to the numbers themselves to that AreClose survives scalar multiplication.
/// 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. This is important enough to repeat:
/// NB: NO CODE CALLING THIS FUNCTION SHOULD DEPEND ON ACCURATE RESULTS - this should be
/// used for optimizations *only*.
///
///
/// bool - the result of the AreClose comparision.
///
/// The first double to compare.
/// The second double to compare.
public static bool AreClose(double value1, double value2)
{
//in case they are Infinities (then epsilon check does not work)
if(value1 == value2) return true;
// This computes (|value1-value2| / (|value1| + |value2| + 10.0)) < DBL_EPSILON
double eps = (Math.Abs(value1) + Math.Abs(value2) + 10.0) * DBL_EPSILON;
double delta = value1 - value2;
return(-eps < delta) && (eps > delta);
}
///
/// 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. Note that this epsilon is proportional to the numbers themselves
/// to that AreClose survives scalar multiplication. Note,
/// 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. This is important enough to repeat:
/// NB: NO CODE CALLING THIS FUNCTION SHOULD DEPEND ON ACCURATE RESULTS - this should be
/// used for optimizations *only*.
///
///
/// bool - the result of the LessThan comparision.
///
/// The first double to compare.
/// The second double to compare.
public static bool LessThan(double value1, double value2)
{
return (value1 < value2) && !AreClose(value1, value2);
}
///
/// 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. Note that this epsilon is proportional to the numbers themselves
/// to that AreClose survives scalar multiplication. Note,
/// 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. This is important enough to repeat:
/// NB: NO CODE CALLING THIS FUNCTION SHOULD DEPEND ON ACCURATE RESULTS - this should be
/// used for optimizations *only*.
///
///
/// bool - the result of the GreaterThan comparision.
///
/// The first double to compare.
/// The second double to compare.
public static bool GreaterThan(double value1, double value2)
{
return (value1 > value2) && !AreClose(value1, value2);
}
///
/// 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. Note that this epsilon is proportional to the numbers
/// themselves to that AreClose survives scalar multiplication. Note,
/// 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. This is important enough to repeat:
/// NB: NO CODE CALLING THIS FUNCTION SHOULD DEPEND ON ACCURATE RESULTS - this should be
/// used for optimizations *only*.
///
///
/// bool - the result of the LessThanOrClose comparision.
///
/// The first double to compare.
/// The second double to compare.
public static bool LessThanOrClose(double value1, double value2)
{
return (value1 < value2) || AreClose(value1, value2);
}
///
/// 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. Note that this epsilon is proportional to the numbers
/// themselves to that AreClose survives scalar multiplication. Note,
/// 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. This is important enough to repeat:
/// NB: NO CODE CALLING THIS FUNCTION SHOULD DEPEND ON ACCURATE RESULTS - this should be
/// used for optimizations *only*.
///
///
/// bool - the result of the GreaterThanOrClose comparision.
///
/// The first double to compare.
/// The second double to compare.
public static bool GreaterThanOrClose(double value1, double value2)
{
return (value1 > value2) || AreClose(value1, value2);
}
///
/// IsOne - Returns whether or not the double is "close" to 1. Same as AreClose(double, 1),
/// but this is faster.
///
///
/// bool - the result of the AreClose comparision.
///
/// The double to compare to 1.
public static bool IsOne(double value)
{
return Math.Abs(value-1.0) < 10.0 * DBL_EPSILON;
}
///
/// IsZero - Returns whether or not the double is "close" to 0. Same as AreClose(double, 0),
/// but this is faster.
///
///
/// bool - the result of the AreClose comparision.
///
/// The double to compare to 0.
public static bool IsZero(double value)
{
return Math.Abs(value) < 10.0 * DBL_EPSILON;
}
// The Point, Size, Rect and Matrix class have moved to WinCorLib. However, we provide
// internal AreClose methods for our own use here.
///
/// Compares two points for fuzzy equality. This function
/// helps compensate for the fact that double values can
/// acquire error when operated upon
///
/// The first point to compare
/// The second point to compare
/// Whether or not the two points are equal
public static bool AreClose(Point point1, Point point2)
{
return DoubleUtil.AreClose(point1.X, point2.X) &&
DoubleUtil.AreClose(point1.Y, point2.Y);
}
///
/// Compares two Size instances for fuzzy equality. This function
/// helps compensate for the fact that double values can
/// acquire error when operated upon
///
/// The first size to compare
/// The second size to compare
/// Whether or not the two Size instances are equal
public static bool AreClose(Size size1, Size size2)
{
return DoubleUtil.AreClose(size1.Width, size2.Width) &&
DoubleUtil.AreClose(size1.Height, size2.Height);
}
///
/// Compares two Vector instances for fuzzy equality. This function
/// helps compensate for the fact that double values can
/// acquire error when operated upon
///
/// The first Vector to compare
/// The second Vector to compare
/// Whether or not the two Vector instances are equal
public static bool AreClose(System.Windows.Vector vector1, System.Windows.Vector vector2)
{
return DoubleUtil.AreClose(vector1.X, vector2.X) &&
DoubleUtil.AreClose(vector1.Y, vector2.Y);
}
///
/// Compares two rectangles for fuzzy equality. This function
/// helps compensate for the fact that double values can
/// acquire error when operated upon
///
/// The first rectangle to compare
/// The second rectangle to compare
/// Whether or not the two rectangles are equal
public static bool AreClose(Rect rect1, Rect rect2)
{
// If they're both empty, don't bother with the double logic.
if (rect1.IsEmpty)
{
return rect2.IsEmpty;
}
// At this point, rect1 isn't empty, so the first thing we can test is
// rect2.IsEmpty, followed by property-wise compares.
return (!rect2.IsEmpty) &&
DoubleUtil.AreClose(rect1.X, rect2.X) &&
DoubleUtil.AreClose(rect1.Y, rect2.Y) &&
DoubleUtil.AreClose(rect1.Height, rect2.Height) &&
DoubleUtil.AreClose(rect1.Width, rect2.Width);
}
///
///
///
///
///
public static bool IsBetweenZeroAndOne(double val)
{
return (GreaterThanOrClose(val, 0) && LessThanOrClose(val, 1));
}
///
///
///
///
///
public static int DoubleToInt(double val)
{
return (0 < val) ? (int)(val + 0.5) : (int)(val - 0.5);
}
///
/// rectHasNaN - this returns true if this rect has X, Y , Height or Width as NaN.
///
/// The rectangle to test
/// returns whether the Rect has NaN
public static bool RectHasNaN(Rect r)
{
if ( DoubleUtil.IsNaN(r.X)
|| DoubleUtil.IsNaN(r.Y)
|| DoubleUtil.IsNaN(r.Height)
|| DoubleUtil.IsNaN(r.Width) )
{
return true;
}
return false;
}
#if !PBTCOMPILER
[StructLayout(LayoutKind.Explicit)]
private struct NanUnion
{
[FieldOffset(0)] internal double DoubleValue;
[FieldOffset(0)] internal UInt64 UintValue;
}
// The standard CLR double.IsNaN() function is approximately 100 times slower than our own wrapper,
// so please make sure to use DoubleUtil.IsNaN() in performance sensitive code.
// PS item that tracks the CLR improvement is DevDiv Schedule : 26916.
// IEEE 754 : If the argument is any value in the range 0x7ff0000000000001L through 0x7fffffffffffffffL
// or in the range 0xfff0000000000001L through 0xffffffffffffffffL, the result will be NaN.
public static bool IsNaN(double value)
{
NanUnion t = new NanUnion();
t.DoubleValue = value;
UInt64 exp = t.UintValue & 0xfff0000000000000;
UInt64 man = t.UintValue & 0x000fffffffffffff;
return (exp == 0x7ff0000000000000 || exp == 0xfff0000000000000) && (man != 0);
}
#endif
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- MouseOverProperty.cs
- Classification.cs
- ItemMap.cs
- VerificationException.cs
- ITreeGenerator.cs
- ObjectParameterCollection.cs
- StateDesigner.TransitionInfo.cs
- LicenseException.cs
- DataGridSortCommandEventArgs.cs
- BitmapFrame.cs
- XmlEntityReference.cs
- CurrencyWrapper.cs
- TextEffect.cs
- DataRowView.cs
- ExceptionDetail.cs
- FontFamily.cs
- PassportIdentity.cs
- MSHTMLHostUtil.cs
- ToolStripItemGlyph.cs
- TypeCollectionPropertyEditor.cs
- xsdvalidator.cs
- HttpConfigurationSystem.cs
- Brush.cs
- PenContext.cs
- BinaryNode.cs
- Int32Storage.cs
- MailHeaderInfo.cs
- StretchValidation.cs
- FrameworkPropertyMetadata.cs
- LocalizeDesigner.cs
- ToolStripScrollButton.cs
- DbConnectionPoolIdentity.cs
- StrokeNodeEnumerator.cs
- WebBrowserNavigatedEventHandler.cs
- GrammarBuilderWildcard.cs
- StaticExtension.cs
- PartBasedPackageProperties.cs
- GridViewRowPresenterBase.cs
- Pair.cs
- RadioButtonStandardAdapter.cs
- AppLevelCompilationSectionCache.cs
- TextDecoration.cs
- DesignerGeometryHelper.cs
- TaiwanCalendar.cs
- TemplateNameScope.cs
- TextTreeInsertElementUndoUnit.cs
- PaintEvent.cs
- CallContext.cs
- SQLMoneyStorage.cs
- Char.cs
- VerificationAttribute.cs
- SelectionGlyphBase.cs
- EmbeddedMailObject.cs
- HttpWebResponse.cs
- SqlDataAdapter.cs
- MetadataStore.cs
- OrderByLifter.cs
- SecureConversationServiceCredential.cs
- SafeRightsManagementPubHandle.cs
- ListViewContainer.cs
- WindowShowOrOpenTracker.cs
- CrossAppDomainChannel.cs
- InstancePersistenceEvent.cs
- FileNameEditor.cs
- SerializationHelper.cs
- Operators.cs
- ProcessDesigner.cs
- ContractCodeDomInfo.cs
- ExpandedWrapper.cs
- WebPartConnectionsDisconnectVerb.cs
- LambdaCompiler.Logical.cs
- WebPartDescriptionCollection.cs
- FixedSOMContainer.cs
- BuildProvider.cs
- TypeConverterAttribute.cs
- MSG.cs
- Misc.cs
- DataGridHeaderBorder.cs
- FontDriver.cs
- FrameworkObject.cs
- InternalSafeNativeMethods.cs
- XmlSchemas.cs
- BorderGapMaskConverter.cs
- SerialErrors.cs
- QueryTaskGroupState.cs
- ListViewDeleteEventArgs.cs
- Attributes.cs
- AppSettingsExpressionBuilder.cs
- NegotiationTokenAuthenticator.cs
- RegexCode.cs
- SqlParameterCollection.cs
- Util.cs
- PropertyRef.cs
- _HeaderInfo.cs
- QilSortKey.cs
- pingexception.cs
- AsymmetricKeyExchangeDeformatter.cs
- InstanceDataCollection.cs
- StreamInfo.cs
- ConstructorBuilder.cs