大数运算(五)

来源:互联网 发布:云点播源码 编辑:程序博客网 时间:2024/05/16 06:26
Author:水如烟 

环境服务和普通函数

注意的是:这里约束了.NET FrameWork版本。主要是地址类中没有设置UnitMaxSize变量。如果地址类带上了这个变量信息,那么,地址在不同版本(这里特指decimal表示的值范围不同)也可以正确转换。那样,这个限制就可以取消了。

CommonFunction.vb

Friend Class CommonFunction
    
Private Sub New()
    
End Sub

    
Public Shared Function Clone(Of T)(ByVal obj As T) As T
        
Dim tmpT As T

        
Dim mFormatter As New System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
        
Dim mMemoryStream As New System.IO.MemoryStream

        
Using mMemoryStream
            mFormatter.Serialize(mMemoryStream, obj)
            mMemoryStream.Position 
= 0
            tmpT 
= CType(mFormatter.Deserialize(mMemoryStream), T)
            mMemoryStream.Close()
        
End Using

        
Return tmpT
    
End Function

    
Public Shared Function SplitStringToArray(ByVal line As StringByVal digits As IntegerAs String()
        
Dim mLineLength As Integer = line.Length
        
Dim mCount As Integer = mLineLength / digits
        
If (mLineLength Mod digits) > 0 Then mCount += 1

        
Dim mResult(mCount - 1As String

        
Dim mCurrentIndex As Integer
        
For i As Integer = mCount - 1 To 0 Step -1
            mCurrentIndex 
= mLineLength - (mCount - i) * digits

            
If mCurrentIndex < 0 Then
                mResult(
0= line.Substring(0, mLineLength - (mCount - 1* digits)
            
Else
                mResult(i) 
= line.Substring(mCurrentIndex, digits)

            
End If

        
Next

        
Return mResult
    
End Function

End Class

Information.vb

UnitMaxSize是核心变量。

Friend Class Information
    
Private Sub New()
    
End Sub

    
Private Shared gUnitMaxSize As Integer
    
Private Shared gUnitDataType As TypeCode

    
''' <summary>
    ''' 运算单元最大位数
    ''' </summary>
    Public Shared ReadOnly Property UnitMaxSize() As Integer
        
Get
            
Return gUnitMaxSize
        
End Get
    
End Property

    
''' <summary>
    ''' 运算单元数据类型
    ''' </summary>
    ''' <value></value>
    Public Shared ReadOnly Property UnitDataType() As TypeCode
        
Get
            
Return gUnitDataType
        
End Get
    
End Property

    
''' <summary>
    ''' 转换为运算单元数据类型
    ''' </summary>
    ''' <param name="Value">值</param>
    Public Shared Function ConverToUnitDataType(ByVal Value As ObjectAs Object
        
Return System.Convert.ChangeType(Value, UnitDataType)
    
End Function

    
Public Shared Function ConverToUnitDataTypeFullString(ByVal Value As ObjectAs String
        
Return Value.ToString.PadLeft(UnitMaxSize, "0"c)
    
End Function

    
Public Shared Function ConverToUnitDataTypeFullString(ByVal Value As ObjectByVal unitNum As IntegerAs String
        
Return Value.ToString.PadLeft(GetUnitLength(unitNum), "0"c)
    
End Function

    
Public Shared Function SplitValueToArray(ByVal Value As StringAs String()
        
Return SplitValueToArray(Value, 0)
    
End Function

    
Public Shared Function SplitValueToArray(ByVal Value As StringByVal unitNum As IntegerAs String()
        
Return CommonFunction.SplitStringToArray(Value, GetUnitLength(unitNum))
    
End Function


    
Public Shared Function AddressConvertFromAToB(ByVal aAddress As IntegerByVal aUnitNum As IntegerByVal bUnitNum As IntegerAs Integer
        
Dim mDiv As Integer
        
Dim mRem As Integer

        mDiv 
= Math.DivRem(CInt(aAddress * Math.Pow(2, aUnitNum)), CInt(Math.Pow(2, bUnitNum)), mRem)

        
If mRem > 0 Then Throw New Exception("转换无效")

        
Return mDiv
    
End Function

    
Public Shared Function GetUnitLength(ByVal unitNum As IntegerAs Integer
        
Return CInt(UnitMaxSize * Math.Pow(2, unitNum))
    
End Function

    
Public Shared Function IsZero(ByVal value As StringAs Boolean
        
Return System.Text.RegularExpressions.Regex.IsMatch(value, "^[0]+$")
    
End Function

    
Public Shared Function GetStringValue(ByVal Value As StringAs String
        
Dim mResult As String = System.Text.RegularExpressions.Regex.Match(Value, "^[0]{0,}(?<Value>[1-9].*)$").Groups("Value").Value
        
If String.IsNullOrEmpty(mResult) Then mResult = "0"
        
Return mResult
    
End Function

    
Public Shared Function GetStringsValue(ByVal valueCollection As Collections.ObjectModel.Collection(Of String), ByVal unitNum As IntegerAs String
        
Return GetStringsValue(valueCollection, 0, unitNum)
    
End Function

    
Public Shared Function GetStringsValue(ByVal valueCollection As Collections.ObjectModel.Collection(Of String), ByVal appendEmptyValueCount As IntegerByVal unitNum As IntegerAs String
        
Return GetStringsValue(valueCollection, 0, valueCollection.Count - 1, appendEmptyValueCount, unitNum)
    
End Function

    
Public Shared Function GetStringsValue(ByVal valueCollection As Collections.ObjectModel.Collection(Of String), ByVal firstIndex As IntegerByVal lastIndex As IntegerByVal unitNum As IntegerAs String
        
Return GetStringsValue(valueCollection, firstIndex, lastIndex, 0, unitNum)
    
End Function

    
Public Shared Function GetStringsValue(ByVal valueCollection As Collections.ObjectModel.Collection(Of String), ByVal firstIndex As IntegerByVal lastIndex As IntegerByVal appendEmptyValueCount As IntegerByVal unitNum As IntegerAs String
        
If firstIndex > lastIndex OrElse firstIndex < 0 OrElse lastIndex > (valueCollection.Count - 1Then Throw New Exception("引用索引无效")

        
Dim b As New System.Text.StringBuilder
        
Dim tmp As String

        
For i As Integer = firstIndex To lastIndex

            
If i = firstIndex Then
                tmp 
= valueCollection(i)
            
Else
                tmp 
= Information.ConverToUnitDataTypeFullString(valueCollection(i), unitNum)
            
End If

            b.Append(tmp)
        
Next

        
For i As Integer = 0 To appendEmptyValueCount - 1
            tmp 
= Information.ConverToUnitDataTypeFullString("0", unitNum)
            b.Append(tmp)
        
Next

        
Return b.ToString
    
End Function

    
Shared Sub New()

        
'寻找可表示为整数的且表示范围最大的数据类型
        Dim mTypeName As String
        
Dim mType As Type
        
Dim mFieldInfo As Reflection.FieldInfo


        
Dim mMaxValue As String = "0"
        
Dim mDataTypeCode As TypeCode

        
Dim mCurrentTypeMaxValue As String = "0"
        
For Each c As TypeCode In [Enum].GetValues(GetType(TypeCode))

            mTypeName 
= c.ToString
            mType 
= Type.GetType(String.Format("System.{0}", mTypeName))

            mFieldInfo 
= mType.GetField("MaxValue")
            
If mFieldInfo Is Nothing Then Continue For

            mCurrentTypeMaxValue 
= mFieldInfo.GetValue(Nothing).ToString

            
If IsNumeric(mCurrentTypeMaxValue) Then
                
If mCurrentTypeMaxValue.Length > mMaxValue.Length Then
                    mMaxValue 
= mCurrentTypeMaxValue
                    mDataTypeCode 
= c
                
End If
            
End If

        
Next

        gUnitDataType 
= mDataTypeCode

        
'确定该数据类型下,可表示的最大位数。保证两数相乘结果仍可表示为整数。
        Dim x As Object
        x 
= ConverToUnitDataType(mMaxValue)

        
Dim mSqrtResult As String = Math.Sqrt(CDbl(x)).ToString '最大数开方

        
Dim mPointIndex As Integer = mSqrtResult.IndexOf("."c) '只取整数部分
        If mPointIndex > 0 Then
            mSqrtResult 
= mSqrtResult.Substring(0, mPointIndex)
        
End If

        
Dim mDigits As Integer = mSqrtResult.ToString.Length - 1 '可表示的最大位数是最大数开方后整数部分位数减一位

        gUnitMaxSize 
= mDigits
    
End Sub

End Class
原创粉丝点击