프로젝트

일반

사용자정보

통계
| 브랜치(Branch): | 개정판:

markus / KCOM / WrapPanel / NumericExtensions.cs @ d18ea2bd

이력 | 보기 | 이력해설 | 다운로드 (4.42 KB)

1
// (c) Copyright Microsoft Corporation.
2
// This source is subject to the Microsoft Public License (Ms-PL).
3
// Please see http://go.microsoft.com/fwlink/?LinkID=131993 for details.
4
// All other rights reserved.
5

    
6
using System;
7
using System.Diagnostics.CodeAnalysis;
8
using System.Runtime.InteropServices;
9

    
10
namespace System.Windows.Controls
11
{
12
    /// <summary>
13
    /// Numeric utility methods used by controls.  These methods are similar in
14
    /// scope to the WPF DoubleUtil class.
15
    /// </summary>
16
    internal static class NumericExtensions
17
    {
18
        /// <summary>
19
        /// NanUnion is a C++ style type union used for efficiently converting
20
        /// a double into an unsigned long, whose bits can be easily
21
        /// manipulated.
22
        /// </summary>
23
        [StructLayout(LayoutKind.Explicit)]
24
        private struct NanUnion
25
        {
26
            /// <summary>
27
            /// Floating point representation of the union.
28
            /// </summary>
29
            [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields", Justification = "It is accessed through the other member of the union")]
30
            [FieldOffset(0)]
31
            internal double FloatingValue;
32

    
33
            /// <summary>
34
            /// Integer representation of the union.
35
            /// </summary>
36
            [FieldOffset(0)]
37
            internal ulong IntegerValue;
38
        }
39

    
40
        /// <summary>
41
        /// Check if a number is zero.
42
        /// </summary>
43
        /// <param name="value">The number to check.</param>
44
        /// <returns>True if the number is zero, false otherwise.</returns>
45
        public static bool IsZero(this double value)
46
        {
47
            // We actually consider anything within an order of magnitude of
48
            // epsilon to be zero
49
            return Math.Abs(value) < 2.2204460492503131E-15;
50
        }
51

    
52
        /// <summary>
53
        /// Check if a number isn't really a number.
54
        /// </summary>
55
        /// <param name="value">The number to check.</param>
56
        /// <returns>
57
        /// True if the number is not a number, false if it is a number.
58
        /// </returns>
59
        public static bool IsNaN(this double value)
60
        {
61
            // Get the double as an unsigned long
62
            NanUnion union = new NanUnion { FloatingValue = value };
63

    
64
            // An IEEE 754 double precision floating point number is NaN if its
65
            // exponent equals 2047 and it has a non-zero mantissa.
66
            ulong exponent = union.IntegerValue & 0xfff0000000000000L;
67
            if ((exponent != 0x7ff0000000000000L) && (exponent != 0xfff0000000000000L))
68
            {
69
                return false;
70
            }
71
            ulong mantissa = union.IntegerValue & 0x000fffffffffffffL;
72
            return mantissa != 0L;
73
        }
74

    
75
        /// <summary>
76
        /// Determine if one number is greater than another.
77
        /// </summary>
78
        /// <param name="left">First number.</param>
79
        /// <param name="right">Second number.</param>
80
        /// <returns>
81
        /// True if the first number is greater than the second, false
82
        /// otherwise.
83
        /// </returns>
84
        public static bool IsGreaterThan(double left, double right)
85
        {
86
            return (left > right) && !AreClose(left, right);
87
        }
88

    
89
        /// <summary>
90
        /// Determine if one number is less than or close to another.
91
        /// </summary>
92
        /// <param name="left">First number.</param>
93
        /// <param name="right">Second number.</param>
94
        /// <returns>
95
        /// True if the first number is less than or close to the second, false
96
        /// otherwise.
97
        /// </returns>
98
        public static bool IsLessThanOrClose(double left, double right)
99
        {
100
            return (left < right) || AreClose(left, right);
101
        }
102

    
103
        /// <summary>
104
        /// Determine if two numbers are close in value.
105
        /// </summary>
106
        /// <param name="left">First number.</param>
107
        /// <param name="right">Second number.</param>
108
        /// <returns>
109
        /// True if the first number is close in value to the second, false
110
        /// otherwise.
111
        /// </returns>
112
        public static bool AreClose(double left, double right)
113
        {
114
            if (left == right)
115
            {
116
                return true;
117
            }
118

    
119
            double a = (Math.Abs(left) + Math.Abs(right) + 10.0) * 2.2204460492503131E-16;
120
            double b = left - right;
121
            return (-a < b) && (a > b);
122
        }
123
    }
124
}
클립보드 이미지 추가 (최대 크기: 500 MB)