Code:
/ Dotnetfx_Vista_SP2 / Dotnetfx_Vista_SP2 / 8.0.50727.4016 / DEVDIV / depot / DevDiv / releases / Orcas / QFE / 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
- WindowsFormsLinkLabel.cs
- EpmSourcePathSegment.cs
- FileDialog_Vista_Interop.cs
- XmlNodeReader.cs
- DetailsViewInsertEventArgs.cs
- FragmentQueryProcessor.cs
- CodeNamespaceImportCollection.cs
- ZipIOZip64EndOfCentralDirectoryLocatorBlock.cs
- Mapping.cs
- DataSourceView.cs
- FrameworkTextComposition.cs
- DesignTimeParseData.cs
- SqlClientFactory.cs
- DataGridViewCheckBoxColumn.cs
- Update.cs
- TransportBindingElement.cs
- WmpBitmapDecoder.cs
- DesignerCategoryAttribute.cs
- EntityCommandCompilationException.cs
- CodeStatement.cs
- DbConnectionPoolOptions.cs
- StorageMappingItemLoader.cs
- JsonEncodingStreamWrapper.cs
- OdbcPermission.cs
- ExchangeUtilities.cs
- WindowHelperService.cs
- CodeAccessSecurityEngine.cs
- FileLoadException.cs
- HtmlFormWrapper.cs
- CompiledIdentityConstraint.cs
- PropertyValueUIItem.cs
- RectangleGeometry.cs
- WindowHideOrCloseTracker.cs
- Point4DValueSerializer.cs
- PersianCalendar.cs
- Hash.cs
- Vector3DAnimationBase.cs
- documentsequencetextpointer.cs
- SecurityException.cs
- IndicShape.cs
- ClientBuildManagerCallback.cs
- SecurityHelper.cs
- DetailsViewUpdateEventArgs.cs
- ApplicationSecurityInfo.cs
- IPEndPointCollection.cs
- SID.cs
- PageThemeParser.cs
- EntityConnectionStringBuilderItem.cs
- BamlResourceDeserializer.cs
- Accessors.cs
- ControlsConfig.cs
- Queue.cs
- MailWriter.cs
- RewritingPass.cs
- NoClickablePointException.cs
- BamlLocalizabilityResolver.cs
- DateTimeConstantAttribute.cs
- BindingValueChangedEventArgs.cs
- WebPartConnectionsCancelEventArgs.cs
- InitializationEventAttribute.cs
- Formatter.cs
- PartialList.cs
- VisualStateChangedEventArgs.cs
- Int32Collection.cs
- BaseTransportHeaders.cs
- ViewBox.cs
- RsaKeyIdentifierClause.cs
- XmlNamespaceMappingCollection.cs
- PointHitTestParameters.cs
- XPathItem.cs
- Delegate.cs
- WebReferencesBuildProvider.cs
- SQLConvert.cs
- XmlEncodedRawTextWriter.cs
- ManagedWndProcTracker.cs
- AddingNewEventArgs.cs
- EntryWrittenEventArgs.cs
- XmlSignatureProperties.cs
- Parser.cs
- LocalServiceSecuritySettingsElement.cs
- PrivateFontCollection.cs
- MimePart.cs
- COM2FontConverter.cs
- CompilationPass2Task.cs
- SerializationObjectManager.cs
- CountAggregationOperator.cs
- DBCSCodePageEncoding.cs
- DebugController.cs
- MobileCapabilities.cs
- BinHexDecoder.cs
- SqlBuilder.cs
- updatecommandorderer.cs
- StringComparer.cs
- UriSectionData.cs
- ApplicationGesture.cs
- PackageRelationshipCollection.cs
- BitmapFrameEncode.cs
- MoveSizeWinEventHandler.cs
- VerticalAlignConverter.cs
- Gdiplus.cs