Author:
水如烟
基本运算单元
这个单元,尽量做到精简,变量能省则省,尽量不在这做条件判断。
MathsUnit.MathUnit.vb
Option
Strict
Off
Partial Class MathsUnit
< Serializable() > _
Private Class MathUnit
Private gCurrentValue As Object
Private gCurrentResult As New CalculateResult
Private gHasCarry As Boolean
Private gCarry As MathUnit
Sub New ()
Clear()
End Sub
Public ReadOnly Property Value() As String
Get
Return Me .gCurrentResult.Value
End Get
End Property
Public ReadOnly Property HasCarry() As Boolean
Get
Return gHasCarry
End Get
End Property
Public ReadOnly Property IsZero() As Boolean
Get
Return gCurrentResult.Value.Equals( " 0 " )
End Get
End Property
Public Sub SetValue( ByVal value As String )
gCurrentValue = Information.ConverToUnitDataType(value)
gCurrentResult.InputValue(value)
gHasCarry = False
gCarry = Nothing
End Sub
Public Function Clone() As MathUnit
Return CommonFunction.Clone( Of MathUnit)( Me )
End Function
Private Sub Clear()
gCurrentValue = Information.ConverToUnitDataType( 0 )
gCurrentResult.InputValue( " 0 " )
gHasCarry = False
gCarry = Nothing
End Sub
' 进位处理
Private Sub ChekCarry() ' 运算单元只保存一次进位。在累加或累乘过程中,若已存在进位,则需先处理进位,否则抛出异常
If gHasCarry Then
Throw New Exception( " 上次运算已有进位,不能再次运算 " )
End If
End Sub
Private Sub ChekCarryNeeded() ' 检测是否需要进位
gCurrentResult.InputValue(gCurrentValue.ToString)
If Not gCurrentResult.HasCarry Then Exit Sub
gHasCarry = True
gCarry = New MathUnit
gCarry.SetValue(gCurrentResult.Carry)
End Sub
Public Sub ReferCarryTo( ByRef unit As MathUnit) ' 向另一个运算单元提交进位
If Not gHasCarry Then Exit Sub
unit.Add( Me .gCarry)
' 提交后
Me .gCarry = Nothing
Me .gHasCarry = False
Me .gCurrentValue = Information.ConverToUnitDataType( Me .gCurrentResult.Value)
End Sub
' 相加
Public Sub Add( ByVal unit As MathUnit)
If unit.gCurrentValue = 0 Then Exit Sub
Me .ChekCarry()
Me .gCurrentValue += unit.gCurrentValue
Me .ChekCarryNeeded()
End Sub
Public Shared Operator + ( ByVal a As MathUnit, ByVal b As MathUnit) As MathUnit
Dim c As MathUnit = a.Clone
c.Add(b)
Return c
End Operator
' 相乘
Public Sub Multy( ByVal multyplier As MathUnit)
If multyplier.gCurrentValue = 0 Then
Me .Clear()
Exit Sub
End If
If Me .gCurrentValue = 0 Then Exit Sub
Me .ChekCarry()
Me .gCurrentValue *= multyplier.gCurrentValue
Me .ChekCarryNeeded()
End Sub
Public Shared Operator * ( ByVal a As MathUnit, ByVal b As MathUnit) As MathUnit
Dim c As MathUnit = a.Clone
c.Multy(b)
Return c
End Operator
' 中间运算结果处理
< Serializable() > _
Private Class CalculateResult
' 运算结果以字串形式传入
Private gInput As String = " 0 "
' 是否有进位
Private gHasCarry As Boolean = False
' 进位值字串
Private gCarry As String = " 0 "
' 值字串
Private gValue As String = " 0 "
Friend ReadOnly Property OrignalValue() As String
Get
Return gInput
End Get
End Property
Friend ReadOnly Property Value() As String
Get
Return gValue
End Get
End Property
Friend ReadOnly Property Carry() As String
Get
Return gCarry
End Get
End Property
Friend ReadOnly Property HasCarry() As Boolean
Get
Return gHasCarry
End Get
End Property
Public Sub InputValue( ByVal value As String )
gInput = value
Initialize()
End Sub
Private Sub Initialize()
Dim mDigits As Integer = gInput.Length
If mDigits <= Information.UnitMaxSize Then
gValue = gInput
gCarry = " 0 "
gHasCarry = False
Else
Dim mIndexSplit As Integer = mDigits - Information.UnitMaxSize
gValue = gInput.Substring(mIndexSplit)
gCarry = gInput.Substring( 0 , mIndexSplit)
gHasCarry = True
End If
End Sub
End Class
End Class
End Class
Partial Class MathsUnit
< Serializable() > _
Private Class MathUnit
Private gCurrentValue As Object
Private gCurrentResult As New CalculateResult
Private gHasCarry As Boolean
Private gCarry As MathUnit
Sub New ()
Clear()
End Sub
Public ReadOnly Property Value() As String
Get
Return Me .gCurrentResult.Value
End Get
End Property
Public ReadOnly Property HasCarry() As Boolean
Get
Return gHasCarry
End Get
End Property
Public ReadOnly Property IsZero() As Boolean
Get
Return gCurrentResult.Value.Equals( " 0 " )
End Get
End Property
Public Sub SetValue( ByVal value As String )
gCurrentValue = Information.ConverToUnitDataType(value)
gCurrentResult.InputValue(value)
gHasCarry = False
gCarry = Nothing
End Sub
Public Function Clone() As MathUnit
Return CommonFunction.Clone( Of MathUnit)( Me )
End Function
Private Sub Clear()
gCurrentValue = Information.ConverToUnitDataType( 0 )
gCurrentResult.InputValue( " 0 " )
gHasCarry = False
gCarry = Nothing
End Sub
' 进位处理
Private Sub ChekCarry() ' 运算单元只保存一次进位。在累加或累乘过程中,若已存在进位,则需先处理进位,否则抛出异常
If gHasCarry Then
Throw New Exception( " 上次运算已有进位,不能再次运算 " )
End If
End Sub
Private Sub ChekCarryNeeded() ' 检测是否需要进位
gCurrentResult.InputValue(gCurrentValue.ToString)
If Not gCurrentResult.HasCarry Then Exit Sub
gHasCarry = True
gCarry = New MathUnit
gCarry.SetValue(gCurrentResult.Carry)
End Sub
Public Sub ReferCarryTo( ByRef unit As MathUnit) ' 向另一个运算单元提交进位
If Not gHasCarry Then Exit Sub
unit.Add( Me .gCarry)
' 提交后
Me .gCarry = Nothing
Me .gHasCarry = False
Me .gCurrentValue = Information.ConverToUnitDataType( Me .gCurrentResult.Value)
End Sub
' 相加
Public Sub Add( ByVal unit As MathUnit)
If unit.gCurrentValue = 0 Then Exit Sub
Me .ChekCarry()
Me .gCurrentValue += unit.gCurrentValue
Me .ChekCarryNeeded()
End Sub
Public Shared Operator + ( ByVal a As MathUnit, ByVal b As MathUnit) As MathUnit
Dim c As MathUnit = a.Clone
c.Add(b)
Return c
End Operator
' 相乘
Public Sub Multy( ByVal multyplier As MathUnit)
If multyplier.gCurrentValue = 0 Then
Me .Clear()
Exit Sub
End If
If Me .gCurrentValue = 0 Then Exit Sub
Me .ChekCarry()
Me .gCurrentValue *= multyplier.gCurrentValue
Me .ChekCarryNeeded()
End Sub
Public Shared Operator * ( ByVal a As MathUnit, ByVal b As MathUnit) As MathUnit
Dim c As MathUnit = a.Clone
c.Multy(b)
Return c
End Operator
' 中间运算结果处理
< Serializable() > _
Private Class CalculateResult
' 运算结果以字串形式传入
Private gInput As String = " 0 "
' 是否有进位
Private gHasCarry As Boolean = False
' 进位值字串
Private gCarry As String = " 0 "
' 值字串
Private gValue As String = " 0 "
Friend ReadOnly Property OrignalValue() As String
Get
Return gInput
End Get
End Property
Friend ReadOnly Property Value() As String
Get
Return gValue
End Get
End Property
Friend ReadOnly Property Carry() As String
Get
Return gCarry
End Get
End Property
Friend ReadOnly Property HasCarry() As Boolean
Get
Return gHasCarry
End Get
End Property
Public Sub InputValue( ByVal value As String )
gInput = value
Initialize()
End Sub
Private Sub Initialize()
Dim mDigits As Integer = gInput.Length
If mDigits <= Information.UnitMaxSize Then
gValue = gInput
gCarry = " 0 "
gHasCarry = False
Else
Dim mIndexSplit As Integer = mDigits - Information.UnitMaxSize
gValue = gInput.Substring(mIndexSplit)
gCarry = gInput.Substring( 0 , mIndexSplit)
gHasCarry = True
End If
End Sub
End Class
End Class
End Class