1 #Region "Microsoft.VisualBasic::33ec11383a0c1f0680f65f1a9fd7d9d0, Microsoft.VisualBasic.Core\Extensions\Math\Percentage.vb"
2
3     ' Author:
4     
5     '       asuka (amethyst.asuka@gcmodeller.org)
6     '       xie (genetics@smrucc.org)
7     '       xieguigang (xie.guigang@live.com)
8     
9     ' Copyright (c) 2018 GPL3 Licensed
10     
11     
12     ' GNU GENERAL PUBLIC LICENSE (GPL3)
13     
14     
15     ' This program is free software: you can redistribute it and/or modify
16     ' it under the terms of the GNU General Public License as published by
17     ' the Free Software Foundation, either version 3 of the License, or
18     ' (at your option) any later version.
19     
20     ' This program is distributed in the hope that it will be useful,
21     ' but WITHOUT ANY WARRANTY; without even the implied warranty of
22     ' MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23     ' GNU General Public License for more details.
24     
25     ' You should have received a copy of the GNU General Public License
26     ' along with this program. If not, see <http://www.gnu.org/licenses/>.
27
28
29
30     ' /********************************************************************************/
31
32     ' Summaries:
33
34     '     Structure Percentage
35     
36     '         Properties: Denominator, FractionExpr, Numerator, One, Value
37     '                     ZERO
38     
39     '         Constructor: (+1 OverloadsSub New
40     '         Function: (+2 Overloads) CompareTo, Equals, GetTypeCode, ToBoolean, ToByte
41     '                   ToChar, ToDateTime, ToDecimal, ToDouble, ToInt16
42     '                   ToInt32, ToInt64, ToSByte, ToSingle, (+3 OverloadsToString
43     '                   ToType, ToUInt16, ToUInt32, ToUInt64, TryParse
44     '         Operators: <, >
45     
46     
47     ' /********************************************************************************/
48
49 #End Region
50
51 Imports System.Runtime.CompilerServices
52 Imports System.Xml.Serialization
53 Imports Microsoft.VisualBasic.Scripting.Runtime
54 Imports r = System.Text.RegularExpressions.Regex
55
56 Namespace Math
57
58     ''' <summary>
59     ''' 分数,百分比
60     ''' </summary>
61     ''' <remarks></remarks>
62     Public Structure Percentage : Implements IComparable, IFormattable, IConvertible, IComparable(Of [Double]), IEquatable(Of [Double])
63
64         ''' <summary>
65         ''' 分子
66         ''' </summary>
67         ''' <remarks></remarks>
68         <XmlAttribute> Public Property Numerator As Double
69         ''' <summary>
70         ''' 分母
71         ''' </summary>
72         ''' <remarks></remarks>
73         <XmlAttribute> Public Property Denominator As Double
74
75         ''' <summary>
76         ''' <see cref="Numerator"></see>/<see cref="Denominator"></see>
77         ''' </summary>
78         ''' <value></value>
79         ''' <returns></returns>
80         ''' <remarks></remarks>
81         <SoapIgnore> Public ReadOnly Property Value As Double
82             <MethodImpl(MethodImplOptions.AggressiveInlining)>
83             Get
84                 If Numerator = 0R Then
85                     Return 0
86                 Else
87                     Return Numerator / Denominator
88                 End If
89             End Get
90         End Property
91
92         <SoapIgnore> Public ReadOnly Property FractionExpr As String
93             <MethodImpl(MethodImplOptions.AggressiveInlining)>
94             Get
95                 Return $"{Numerator}/{Denominator}"
96             End Get
97         End Property
98
99         ''' <summary>
100         ''' <paramref name="n"/> / <paramref name="d"/>
101         ''' </summary>
102         ''' <param name="n"></param>
103         ''' <param name="d"></param>
104         Sub New(n As Double, d As Double)
105             Numerator = n
106             Denominator = d
107         End Sub
108
109         Public Overrides Function ToString() As String
110             Return String.Format("{0}/{1} ({2}%)", Numerator, Denominator, Value)
111         End Function
112
113         ''' <summary>
114         ''' 
115         ''' </summary>
116         ''' <param name="Text">``\d+[/]\d+ \(\d+[%]\)``</param>
117         ''' <returns></returns>
118         ''' <remarks></remarks>
119         Public Shared Function TryParse(Text As StringAs Percentage
120             If String.IsNullOrEmpty(Text) Then
121                 Return ZERO
122             End If
123
124             Dim matchs$() = r.Matches(Text, "\d+").ToArray
125             Dim n As Double = matchs(0).RegexParseDouble
126             Dim d As Double = matchs(1).RegexParseDouble
127
128             Return New Percentage With {
129                 .Numerator = n,
130                 .Denominator = d
131             }
132         End Function
133
134         Public Shared ReadOnly Property ZERO As New Percentage(0, 1)
135         Public Shared ReadOnly Property OnAs New Percentage(1, 1)
136
137         <MethodImpl(MethodImplOptions.AggressiveInlining)>
138         Public Shared Narrowing Operator CType(value As Percentage) As Double
139             Return value.Value
140         End Operator
141
142         <MethodImpl(MethodImplOptions.AggressiveInlining)>
143         Public Shared Operator >(value As Percentage, n As DoubleAs Boolean
144             Return value.Value > n
145         End Operator
146
147         <MethodImpl(MethodImplOptions.AggressiveInlining)>
148         Public Shared Operator <(value As Percentage, n As DoubleAs Boolean
149             Return value.Value < n
150         End Operator
151
152 #Region "Public Interface"
153         Public Function CompareTo(obj As ObjectAs Integer Implements IComparable.CompareTo
154             If obj Is Nothing Then
155                 Return 1
156             End If
157             If obj.GetType Is GetType(Double) Then
158                 Return Value.CompareTo(DirectCast(obj, Double))
159             ElseIf obj.GetType Is GetType(Percentage) Then
160                 Return Value.CompareTo(DirectCast(obj, Percentage).Value)
161             Else
162                 Return 1
163             End If
164         End Function
165
166         <MethodImpl(MethodImplOptions.AggressiveInlining)>
167         Public Overloads Function ToString(format As String, formatProvider As IFormatProvider) As String Implements IFormattable.ToString
168             Return Value.ToString(format, formatProvider)
169         End Function
170
171 #Region "Implements IConvertible"
172         <MethodImpl(MethodImplOptions.AggressiveInlining)>
173         Public Function GetTypeCode() As TypeCode Implements IConvertible.GetTypeCode
174             Return TypeCode.Double
175         End Function
176
177         Private Function ToBoolean(provider As IFormatProvider) As Boolean Implements IConvertible.ToBoolean
178             Throw New NotImplementedException()
179         End Function
180
181         Private Function ToChar(provider As IFormatProvider) As Char Implements IConvertible.ToChar
182             Throw New NotImplementedException()
183         End Function
184
185         Private Function ToSByte(provider As IFormatProvider) As SByte Implements IConvertible.ToSByte
186             Throw New NotImplementedException()
187         End Function
188
189         Private Function ToByte(provider As IFormatProvider) As Byte Implements IConvertible.ToByte
190             Throw New NotImplementedException()
191         End Function
192
193         Private Function ToInt16(provider As IFormatProvider) As Short Implements IConvertible.ToInt16
194             Throw New NotImplementedException()
195         End Function
196
197         Private Function ToUInt16(provider As IFormatProvider) As UShort Implements IConvertible.ToUInt16
198             Throw New NotImplementedException()
199         End Function
200
201         Private Function ToInt32(provider As IFormatProvider) As Integer Implements IConvertible.ToInt32
202             Throw New NotImplementedException()
203         End Function
204
205         Private Function ToUInt32(provider As IFormatProvider) As UInteger Implements IConvertible.ToUInt32
206             Throw New NotImplementedException()
207         End Function
208
209         Private Function ToInt64(provider As IFormatProvider) As Long Implements IConvertible.ToInt64
210             Throw New NotImplementedException()
211         End Function
212
213         Private Function ToUInt64(provider As IFormatProvider) As ULong Implements IConvertible.ToUInt64
214             Throw New NotImplementedException()
215         End Function
216
217         Private Function ToSingle(provider As IFormatProvider) As Single Implements IConvertible.ToSingle
218             Throw New NotImplementedException()
219         End Function
220
221         Private Function ToDouble(provider As IFormatProvider) As Double Implements IConvertible.ToDouble
222             Throw New NotImplementedException()
223         End Function
224
225         Private Function ToDecimal(provider As IFormatProvider) As Decimal Implements IConvertible.ToDecimal
226             Throw New NotImplementedException()
227         End Function
228
229         Private Function ToDateTime(provider As IFormatProvider) As Date Implements IConvertible.ToDateTime
230             Throw New NotImplementedException()
231         End Function
232
233         <MethodImpl(MethodImplOptions.AggressiveInlining)>
234         Public Overloads Function ToString(provider As IFormatProvider) As String Implements IConvertible.ToString
235             Return Value.ToString(provider)
236         End Function
237
238         Private Function ToType(conversionType As Type, provider As IFormatProvider) As Object Implements IConvertible.ToType
239             Throw New NotImplementedException()
240         End Function
241 #End Region
242
243         <MethodImpl(MethodImplOptions.AggressiveInlining)>
244         Public Function CompareTo(other As DoubleAs Integer Implements IComparable(Of Double).CompareTo
245             Return Value.CompareTo(other)
246         End Function
247
248         <MethodImpl(MethodImplOptions.AggressiveInlining)>
249         Public Overloads Function Equals(other As DoubleAs Boolean Implements IEquatable(Of Double).Equals
250             Return Value.Equals(other)
251         End Function
252 #End Region
253     End Structure
254 End Namespace