电信主站 网通分站
购买流程 付款方式 常见问题 在线提问 续租服务 购物车
用户名: 密 码: 忘记密码?
首 页
域名注册
虚拟主机
双线主机
服务器租用
VPS主机
企业邮局
代理专区
客服中心
虚拟主机行业资讯 虚拟主机评测对比 互联网最新动态 技术学院 站长资讯 在线教程 网站运营
搜索优化 服务器 网络编程 图形图象 站长之家 网页制作 操作系统
冲浪宝典 软件教学 视频通信 办公软件 邮件系统 网络安全 认证考试
您当前位置:西部数码->资讯中心-> 网站运营-> 网站运营
大数运算(一)-.NET教程,评论及其它
作者:网友供稿 点击:16
  西部数码-全国虚拟主机10强!20余项虚拟主机管理功能,全国领先!第6代双线路虚拟主机,南北访问畅通无阻!虚拟主机可在线rar解压,自动数据恢复设置虚拟目录等.虚拟主机免费赠送访问统计,企业邮局.Cn域名注册10元/年,自助建站480元起,免费试用7天,满意再付款!P4主机租用799元/月.月付免压金!
文章页数:[1] 

大数运算,值的存储和分割

 author:水如烟 

一时兴起做做看看,发现真的不简单,花时间,头大。不过体会也相应深些。

运算单元改了又改。在基本运算单元中,变量能简则简,条件检测尽可能的放在外围。

下面的代码是关于大数值的存储和分割。其中把握好地址是关键。因为数值是分块运算的,如果地址转换不正确,最后合并结果时肯定也不正确的了。这个稍经修改,可以用来写文件切合器。区别是,处理对象不同,一是字符,一是字节。

整体的我还没做好。也是一个单元一个单元的做。如往后需要修改补充,以最后供下载的代码为准。

 

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 1 测试,不用太大。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(cint(unitmaxsize * math.pow(2, 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, cint(unitmaxsize * math.pow(2, unitnum)))
    
end function


    
public shared function addressconvertfromatob(byval aaddress as integerbyval aunitnum as integerbyval bunitnum as integeras integer
        
if (aaddress * math.pow(2, aunitnum)) mod math.pow(2, bunitnum) > 0 then throw new exception("转换无效")
        
return cint(aaddress * math.pow(2, aunitnum) / (math.pow(2, bunitnum)))
    
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
        
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

 

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

 

 

<serializable()> _
public class addressinformation
    
private gaddress as integer = 0
    
private gunitnum as integer = 0

    
public property address() as integer
        
get
            
return gaddress
        
end get
        
friend set(byval value as integer)
            gaddress 
= value
        
end set
    
end property


    
public readonly property unitnum() as integer
        
get
            
return gunitnum
        
end get
    
end property

    
friend sub add(byval value as integer)
        gaddress 
+= value
    
end sub

    
friend sub setzero()
        gaddress 
= 0
    
end sub

    
friend sub increase()
        gaddress 
+= 1
    
end sub

    
friend sub resetaddressfrom(byval address as integerbyval unitnum as integer)
        gaddress 
= addressconvertfromatob(address, unitnum, gunitnum)
    
end sub

    
friend sub copyaddressto(byref addressinfo as addressinformation)
        addressinfo.gaddress 
= addressconvertfromatob(gaddress, gunitnum, addressinfo.gunitnum)
    
end sub

    
friend sub new()
    
end sub

    
friend sub new(byval unitnum as integer)
        gunitnum 
= unitnum
    
end sub

    
public function clone() as addressinformation
        
return commonfunction.clone(of addressinformation)(me)
    
end function

    
public function convertto(byval unitnum as integeras addressinformation
        
dim maddressinfo as new addressinformation(unitnum)
        copyaddressto(maddressinfo)
        
return maddressinfo
    
end function

    
private shared function addressconvertfromatob(byval aaddress as integerbyval aunitnum as integerbyval bunitnum as integeras integer
        
return information.addressconvertfromatob(aaddress, aunitnum, bunitnum)
    
end function

    
public shadows function tostring() as string
        
return string.format("unitnum :{0}, address :{1}", gunitnum, gaddress)
    
end function
end class

 

 

<serializable()> _
public class stringvalue
    
private gorignaladdressinfo as addressinformation
    
private gfirstaddressinfo as addressinformation
    
private glastaddressinfo as addressinformation

    
private gvaluearray as new system.collections.objectmodel.collection(of string)

    
friend readonly property valuecollection() as system.collections.objectmodel.collection(of string)
        
get
            
return gvaluearray
        
end get
    
end property

    
friend readonly property orignaladdressinfo() as addressinformation
        
get
            
return gorignaladdressinfo
        
end get
    
end property

    
public readonly property firstaddressinfo() as addressinformation
        
get
            
return gfirstaddressinfo
        
end get
    
end property

    
public readonly property lastaddressinfo() as addressinformation
        
get
            
return glastaddressinfo
        
end get
    
end property

    
public readonly property unitlength() as integer
        
get
            
return cint(information.unitmaxsize * math.pow(2, gfirstaddressinfo.unitnum))
        
end get
    
end property

    
public readonly property size() as integer
        
get
            
return glastaddressinfo.address - gfirstaddressinfo.address + 1
        
end get
    
end property

    
public readonly property fullvalue() as string
        
get
            
return getfullvalue()
        
end get
    
end property

    
private function getfullvalue() as string

        
return information.getstringsvalue(gvaluearray, gfirstaddressinfo.address - gorignaladdressinfo.address, gfirstaddressinfo.unitnum)
    
end function

    
public readonly property value() as string
        
get
            
return getvalue()
        
end get
    
end property

    
private function getvalue() as string

        
return information.getstringsvalue(gvaluearray, gfirstaddressinfo.unitnum)
    
end function

    
private sub initialize(byval value as string)
        gorignaladdressinfo 
= gfirstaddressinfo.clone

        
if information.iszero(value) then
            gvaluearray.add(
"0")
        
else
            
处理这种情形0000000000000000000000000012344505454564646900000000000000000
            dim tmpvaluearray as string() = information.splitvaluetoarray(value, gfirstaddressinfo.unitnum)

            
忽略前面是零的项;每项,如全是0用一个0表示(000000000000=0),否则忽略开头的0(00000012300=12300)
            dim mcurrentvalue as string
            
dim mfirstiszero as boolean = true

            
for i as integer = 0 to tmpvaluearray.length - 1
                mcurrentvalue 
= information.getstringvalue(tmpvaluearray(i))

                mfirstiszero 
= mfirstiszero and mcurrentvalue.equals("0")
                
if not mfirstiszero then
                    gvaluearray.add(mcurrentvalue)
                
end if
            
next

            
最后面连续项全是0的,当进位处理,地址前移,移去这些项
            dim mlastiszero as boolean = true
            
dim mcount as integer = 0
            
do until not mlastiszero
                mlastiszero 
= mlastiszero and gvaluearray(gvaluearray.count - 1).equals("0")
                
if mlastiszero then
                    mcount 
+= 1
                    gvaluearray.removeat(gvaluearray.count 
- 1)
                
end if
            
loop

            
if mcount > 0 then gfirstaddressinfo.add(mcount)
        
end if


        glastaddressinfo 
= gfirstaddressinfo.clone
        glastaddressinfo.add(gvaluearray.count 
- 1)
    
end sub

    
friend sub new(byval value as string)
        gfirstaddressinfo 
= new addressinformation()

        initialize(value)
    
end sub

    
friend sub new(byval unitnum as integerbyval address as integerbyval value as string)
        gfirstaddressinfo 
= new addressinformation(unitnum)
        gfirstaddressinfo.address 
= address

        initialize(value)
    
end sub


    
friend sub new(byval addressinfo as addressinformation, byval value as string)
        gfirstaddressinfo 
= addressinfo.clone

        initialize(value)
    
end sub

    
public function test_outputvalueinformation() as string
        
dim mformat as string = "({0},{1})"

        
dim b as new system.text.stringbuilder
        
for i as integer = 0 to size - 1

            b.append(
string.format(mformat, glastaddressinfo.address - i, gvaluearray(i)))
        
next

        
return b.tostring
    
end function

    
private function getaddress(byval index as integeras integer
        
return glastaddressinfo.address - index
    
end function

    
private function getindex(byval address as integeras integer
        
return glastaddressinfo.address - address
    
end function

    
public function copytobyindex(byval unitnum as integerbyval index as integeras stringvalue

        
return copytobyindex(unitnum, index, index)
    
end function

    
public function copytobyindex(byval unitnum as integerbyval firstindex as integerbyval lastindex as integeras stringvalue
        
if (firstindex > lastindex) orelse (firstindex < 0 orelse lastindex > me.size) then throw new exception("引用索引无效")

        
dim maddressinfo as addressinformation = gfirstaddressinfo.convertto(unitnum)
        maddressinfo.resetaddressfrom(getaddress(lastindex), gfirstaddressinfo.unitnum) 
地址以lastindex地址为参照

        
dim mvalue as string
        mvalue 
= information.getstringsvalue(gvaluearray, firstindex, lastindex, gfirstaddressinfo.unitnum)

        
return new stringvalue(maddressinfo, mvalue)
    
end function

    
public function copytobyaddress(byval unitnum as integerbyval address as integeras stringvalue
        
return copytobyindex(unitnum, getindex(address))
    
end function

    
public function copytobyaddress(byval unitnum as integerbyval firstaddress as integerbyval lastaddress as integeras stringvalue
        
return copytobyindex(unitnum, getindex(lastaddress), getindex(firstaddress))
    
end function

    
public function copyto(byval unitnum as