求解思路:
对于carry状态,两串对应bit相加,结果为ONE+ONE=ZERO则标记GEN,为ONE标记PROP,ZERO+ZERO=ZERO标记为STOP
定义copy函数,使得用scani copy 操作上述所得串,GEN开始向右将非STOP标记的所有bit修改为ZERO,遇到STOP标记的ZERO停止,并将之改为ONE
对于GEN右侧所有的GEN标记过的bit进行加一操作
map转换至bit串
functor MkBigNumAdd(structure U : BIGNUM_UTIL) : BIGNUM_ADD =
struct
structure Util = U
open Util
open Seq
(* Remove this line when you're done. *)
exception NotYetImplemented
infix 6 ++
datatype carry = GEN | PROP | STOP | None
fun Copy (L,R) =
case (L,R) of
((_,GEN),(_,STOP)) => (ONE,STOP)
| ((_,GEN),(_,GEN)) => (ZERO,GEN)
| ((_,STOP),(_,GEN)) => (ZERO,GEN)
| ((_,PRO),(_,GEN)) => (ZERO,GEN)
| ((_,GEN),(_,PROP)) => (ZERO,GEN)
| ((_,PROP),(_,STOP)) => (ZERO,STOP)
| ((ONE,STOP),(ONE,STOP)) => (ONE,PROP)
| ((ONE,STOP),(ZERO,STOP)) => (ZERO,STOP)
| ((ZERO,STOP),(ZERO,STOP)) => (ZERO,STOP)
| ((ZERO,STOP),(ONE,STOP)) => (ONE,STOP)
| ((_,PROP),(_,PROP)) => (ONE,PROP)
| ((_,STOP),(_,PROP)) => (ONE,STOP)
| ((_,None),(_,_)) => R
fun Change ((nl,ll),(nr,lr)) =
if lr = GEN then (if nl = ONE then (ZERO,lr) else (nr,PROP))
else (nl,ll)
fun x ++ y =
case (length x,length y) of
(0,0) => empty ()
| (_,0) => x
| (0,_) => y
| (m,n) =>
let
val (Left,Right) = if m>n then (x,y) else (y,x)
val Temp = map (fn x => (ZERO,STOP)) Left
val PreMask = map (fn x => if x=ONE then (ONE,GEN) else (ZERO,STOP)) Right
val Mask = append (PreMask,subseq Temp (length Right,length Left - length Right))
val PreSeq = map (fn x => if x=ONE then (ONE,PROP) else (ZERO,STOP)) Left
val ReSeq = map2 Change PreSeq Mask
(*val SecMask = append (singleton (ZERO,STOP),ReSeq)
val TrdMask = map2 (fn ((nl,ll),(nr,lr)) => if ll=GEN andalso lr=GEN then (ONE,GEN) else (ZERO,STOP)) ReSeq SecMask
val ForMask = append (TrdMask , singleton (ZERO,STOP))*)
val Result = scani Copy (ZERO,None) ReSeq
val n = length Result
val FivMask = map2 (fn ((nl,ll),(nr,lr)) => (nl,lr)) ReSeq Result
val SixMask = append (singleton (ZERO,STOP),FivMask )
val SevMask = map2 (fn ((nl,ll),(nr,lr)) => if ((ll=lr)andalso(ll=GEN)) then (ONE,GEN) else (nl,ll)) ReSeq SixMask
val EghMask = append (SevMask , singleton (ZERO,STOP))
val SecResult = if #1 (nth Result (n-1)) = ZERO then append (Result , singleton (ONE,STOP))
else Result
val PreSult = map (fn (n,l) => n ) (map2 (fn ((nl,ll),(nr,lr)) => if (nr=ONE andalso lr=GEN) then (nr,lr) (*else if ll=PROP then (ZERO,GEN)*) else (nl,ll)) SecResult EghMask)
in
PreSult
end
val add = op++
end
求解思路:
计算机中,x的相反数-x为对x逐位取反后加一,后进行加法操作即可,注意舍去最后的符号位
functor MkBigNumSubtract(structure BNA : BIGNUM_ADD) : BIGNUM_SUBTRACT =
struct
structure Util = BNA.Util
open Util
open Seq
(* Remove this line when you're done. *)
exception NotYetImplemented
infix 6 ++ --
fun x ++ y = BNA.add (x, y)
fun Reverse BigNum =
let
val Temp = map (fn x => if x=ONE then ZERO else ONE) BigNum
val One = singleton ONE
in
Temp ++ One
end
fun x -- y =
case (length x,length y) of
(0,0) => empty ()
| (_,0) => x
| (0,_) => Reverse y
| (m,n) =>
let
val Temp = map (fn x => ZERO) x
val Ty = append (y,subseq Temp (n,m-n))
in
subseq (x ++ Reverse Ty) (0,m)
end
val sub = op--
end
求解思路:
对于二进制数A、B
A*B = ( p*2^(m/2) +q )*( r*2^(n/2) + s ) = pr(2^n - 2^(n/2)) + (p +q)*(r +s)*2^(n/2) + (1-2^(n/2))*qs
从而分而治之
functor MkBigNumMultiply(structure BNA : BIGNUM_ADD
structure BNS : BIGNUM_SUBTRACT
sharing BNA.Util = BNS.Util) : BIGNUM_MULTIPLY =
struct
structure Util = BNA.Util
open Primitives
open Util
open Seq
(* Remove this line when you're done. *)
exception NotYetImplemented
infix 6 ++ --
infix 7 **
(* A*B = ( p*2^(m/2) +q )*( r*2^(n/2) + s ) = pr(2^n - 2^(n/2)) + (p +q)*(r +s)*2^(n/2) + (1-2^(n/2))*qs*)
fun x ++ y = BNA.add (x, y)
fun x -- y = BNS.sub (x, y)
fun x ** y =
case (length x,length y) of
(0,_) => empty ()
| (_,0) => empty ()
| (1,1) => if (nth x 0) = ONE andalso (nth y 0) = ONE then singleton ONE else singleton ZERO
| (m,n) =>
let
val len = if m > n then m else n
val mid = len div 2
val (q,p,s,r) =
(subseq x (0,mid),subseq x (mid,m - mid),subseq y (0,mid),subseq y (mid,n - mid))
val (sum1,sum2) = (p ++ q,r ++ s)
val (pr,qs,tp) = par3 (fn () => p ** r,fn () => q ** s,fn () => sum1 ** sum2 )
val Temp = tp -- pr -- qs
val Q1 = append ((tabulate (fn i => ZERO) (mid*2)),pr)
val Q2 = append ((tabulate (fn i => ZERO) mid),Temp)
in
Q1 ++ Q2 ++ qs
end
val mul = op**
end