Author:
水如烟
运算单元组单元 加法
想不到,在运算器中,原来加法是最重要最关键也最复杂的。原来以为是乘法。谁知乘法是那么的简单。
此中地址处理是关键。
MathsUnit.Add.vb
Partial
Class
MathsUnit
Public Sub Add( ByVal unit As MathsUnit)
gIsZero = gIsZero And unit.gIsZero
Dim n As Integer = Me .gAddressInfo.Address
Dim m As Integer = unit.gAddressInfo.Address
Dim l As Integer = Me .Length
Dim k As Integer = unit.Length
Dim d As Integer = n - m
Dim t As Integer = l - k
If d = 0 Then
If t >= 0 Then
' aaaaaaaaaaaaaaaaaa
' bbbbbbbbbbbbbb
Me .gCarryInfo.Clear()
Me .MathUnitAdd(t, k, - t, unit)
Me .ReferCarry()
Else
' aaaaaaaa
' bbbbbbbbbbbbbb
Me .gCarryInfo.Clear()
Me .MathUnitAdd( 0 , l, - t, unit)
Me .LeftInsertMathUnit( - t - 1 , - t, unit)
If Me .gCarryInfo.HasCarry Then Me .gCarryInfo.AddOffset( - t)
Me .ReferCarry()
End If
ElseIf d > 0 Then
Dim p As Integer = d - k
If p >= 0 Then
' aaaaaaa________
' bbbbbbb
Me .RightAddNewMathUnit(p)
Me .RightAddMathUnit( 0 , k, unit)
Else
Dim q As Integer = l + p
If q >= 0 Then
' aaaaaaaaaaa________
' bbbbbbbbbbbbbbbb
Me .gCarryInfo.Clear()
Me .MathUnitAdd(q, - p, - q, unit)
Me .RightAddMathUnit( - p, d, unit)
Me .ReferCarry()
Else
' aaaaaaaaa________
' bbbbbbbbbbbbbbbbbbbb
Me .gCarryInfo.Clear()
Me .MathUnitAdd( 0 , l, - q, unit)
Me .RightAddMathUnit( - p, d, unit)
Me .LeftInsertMathUnit( - q - 1 , - q, unit)
Me .gCarryInfo.AddOffset( - q)
Me .ReferCarry()
End If
End If
' 地址后移d个单位
Me .gAddressInfo.Add( - d)
Else
d = - d
Dim p As Integer = d - l
If p >= 0 Then
' aaaaaa
' bbbbbb________
Me .LeftInsertnewMathUnit(p)
Me .LeftInsertMathUnit(k - 1 , k, unit)
Else
Dim q As Integer = k + p
If q >= 0 Then
' aaaaaaaaaaaaaaa
' bbbbbbbbbbbbbbb_____
Me .gCarryInfo.Clear()
Me .MathUnitAdd( 0 , - p, q, unit)
Me .LeftInsertMathUnit(q - 1 , q, unit)
Me .gCarryInfo.AddOffset(q)
Me .ReferCarry()
Else
' aaaaaaaaaaaaaaaaaaaaaaaa
' bbbbbbbbbbbbbb_____
Me .gCarryInfo.Clear()
Me .MathUnitAdd( - q, k, q, unit)
Me .ReferCarry()
End If
End If
End If
End Sub
Private Sub LeftInsertMathUnit( ByVal bLastIndex As Integer , ByVal totalLen As Integer , ByVal unit As MathsUnit)
For i As Integer = bLastIndex To bLastIndex - totalLen + 1 Step - 1
Me .gMathUnits.Insert( 0 , unit.gMathUnits(i).Clone)
Next
End Sub
Private Sub LeftInsertnewMathUnit( ByVal count As Integer )
For i As Integer = 0 To count - 1
Me .gMathUnits.Insert( 0 , New MathUnit)
Next
End Sub
Private Sub RightAddNewMathUnit( ByVal count As Integer )
For i As Integer = 0 To count - 1
Me .gMathUnits.Add( New MathUnit)
Next
End Sub
Private Sub RightAddMathUnit( ByVal bFirstIndex As Integer , ByVal totalLen As Integer , ByVal unit As MathsUnit)
For i As Integer = bFirstIndex To bFirstIndex + totalLen - 1
Me .gMathUnits.Add(unit.gMathUnits(i).Clone)
Next
End Sub
Private Sub MathUnitAdd( ByVal myFirstIndex As Integer , ByVal totalLen As Integer , ByVal offset As Integer , ByVal unit As MathsUnit)
Dim tmpMathUnit As MathUnit
For i As Integer = myFirstIndex To myFirstIndex + totalLen - 1
tmpMathUnit = Me .gMathUnits(i)
With tmpMathUnit
.Add(unit.gMathUnits(i + offset))
If .HasCarry Then Me .gCarryInfo.SetValue(i)
End With
Next
End Sub
Public Shared Operator + ( ByVal a As MathsUnit, ByVal b As MathsUnit) As MathsUnit
Dim c As MathsUnit = a.Clone
c.Add(b)
Return c
End Operator
End Class
Public Sub Add( ByVal unit As MathsUnit)
gIsZero = gIsZero And unit.gIsZero
Dim n As Integer = Me .gAddressInfo.Address
Dim m As Integer = unit.gAddressInfo.Address
Dim l As Integer = Me .Length
Dim k As Integer = unit.Length
Dim d As Integer = n - m
Dim t As Integer = l - k
If d = 0 Then
If t >= 0 Then
' aaaaaaaaaaaaaaaaaa
' bbbbbbbbbbbbbb
Me .gCarryInfo.Clear()
Me .MathUnitAdd(t, k, - t, unit)
Me .ReferCarry()
Else
' aaaaaaaa
' bbbbbbbbbbbbbb
Me .gCarryInfo.Clear()
Me .MathUnitAdd( 0 , l, - t, unit)
Me .LeftInsertMathUnit( - t - 1 , - t, unit)
If Me .gCarryInfo.HasCarry Then Me .gCarryInfo.AddOffset( - t)
Me .ReferCarry()
End If
ElseIf d > 0 Then
Dim p As Integer = d - k
If p >= 0 Then
' aaaaaaa________
' bbbbbbb
Me .RightAddNewMathUnit(p)
Me .RightAddMathUnit( 0 , k, unit)
Else
Dim q As Integer = l + p
If q >= 0 Then
' aaaaaaaaaaa________
' bbbbbbbbbbbbbbbb
Me .gCarryInfo.Clear()
Me .MathUnitAdd(q, - p, - q, unit)
Me .RightAddMathUnit( - p, d, unit)
Me .ReferCarry()
Else
' aaaaaaaaa________
' bbbbbbbbbbbbbbbbbbbb
Me .gCarryInfo.Clear()
Me .MathUnitAdd( 0 , l, - q, unit)
Me .RightAddMathUnit( - p, d, unit)
Me .LeftInsertMathUnit( - q - 1 , - q, unit)
Me .gCarryInfo.AddOffset( - q)
Me .ReferCarry()
End If
End If
' 地址后移d个单位
Me .gAddressInfo.Add( - d)
Else
d = - d
Dim p As Integer = d - l
If p >= 0 Then
' aaaaaa
' bbbbbb________
Me .LeftInsertnewMathUnit(p)
Me .LeftInsertMathUnit(k - 1 , k, unit)
Else
Dim q As Integer = k + p
If q >= 0 Then
' aaaaaaaaaaaaaaa
' bbbbbbbbbbbbbbb_____
Me .gCarryInfo.Clear()
Me .MathUnitAdd( 0 , - p, q, unit)
Me .LeftInsertMathUnit(q - 1 , q, unit)
Me .gCarryInfo.AddOffset(q)
Me .ReferCarry()
Else
' aaaaaaaaaaaaaaaaaaaaaaaa
' bbbbbbbbbbbbbb_____
Me .gCarryInfo.Clear()
Me .MathUnitAdd( - q, k, q, unit)
Me .ReferCarry()
End If
End If
End If
End Sub
Private Sub LeftInsertMathUnit( ByVal bLastIndex As Integer , ByVal totalLen As Integer , ByVal unit As MathsUnit)
For i As Integer = bLastIndex To bLastIndex - totalLen + 1 Step - 1
Me .gMathUnits.Insert( 0 , unit.gMathUnits(i).Clone)
Next
End Sub
Private Sub LeftInsertnewMathUnit( ByVal count As Integer )
For i As Integer = 0 To count - 1
Me .gMathUnits.Insert( 0 , New MathUnit)
Next
End Sub
Private Sub RightAddNewMathUnit( ByVal count As Integer )
For i As Integer = 0 To count - 1
Me .gMathUnits.Add( New MathUnit)
Next
End Sub
Private Sub RightAddMathUnit( ByVal bFirstIndex As Integer , ByVal totalLen As Integer , ByVal unit As MathsUnit)
For i As Integer = bFirstIndex To bFirstIndex + totalLen - 1
Me .gMathUnits.Add(unit.gMathUnits(i).Clone)
Next
End Sub
Private Sub MathUnitAdd( ByVal myFirstIndex As Integer , ByVal totalLen As Integer , ByVal offset As Integer , ByVal unit As MathsUnit)
Dim tmpMathUnit As MathUnit
For i As Integer = myFirstIndex To myFirstIndex + totalLen - 1
tmpMathUnit = Me .gMathUnits(i)
With tmpMathUnit
.Add(unit.gMathUnits(i + offset))
If .HasCarry Then Me .gCarryInfo.SetValue(i)
End With
Next
End Sub
Public Shared Operator + ( ByVal a As MathsUnit, ByVal b As MathsUnit) As MathsUnit
Dim c As MathsUnit = a.Clone
c.Add(b)
Return c
End Operator
End Class