-- sbDiv : Division of two (corrected) signed binary streams. This -- function is used by the sbfDiv function. Note that negative -- denominator streams result in the negation of both -- denominator and numerator so the denominator is positive. sbDiv :: SBinStream -> SBinStream -> DyStream sbDiv x ( 1:y) = sbDiv' x (1:y) sbDiv x (-1:y) = sbDiv' (sbNegate x) (1:sbNegate y) sbDiv _ ( 0:_) = undefined sbDiv _ ( 1: -1: _) = undefined sbDiv _ (-1: 1: _) = undefined -- sbDiv_emit : Generate specified dyadic digit and make the appropriate -- recursive call. This function makes the code more -- readable. Used by sbDiv'. sbDiv_emit :: Int -> SBinStream -> SBinStream -> DyStream sbDiv_emit ( 4) x y = (dyd_One : sbDiv' x y) sbDiv_emit ( 2) x y = (dyd_Half : sbDiv' x y) sbDiv_emit ( 1) x y = (dyd_Quarter : sbDiv' x y) sbDiv_emit ( 0) x y = (dyd_Zero : sbDiv' x y) sbDiv_emit (-1) x y = (dyd_minusQuarter : sbDiv' x y) sbDiv_emit (-2) x y = (dyd_minusHalf : sbDiv' x y) sbDiv_emit (-4) x y = (dyd_minusOne : sbDiv' x y) -- sbDiv' : The body of the division algorithm, used by sbDiv. sbDiv' :: SBinStream -> SBinStream -> DyStream sbDiv' ( 1: -1:x') y = (sbDiv_emit 0 ( 1:x') y) sbDiv' (-1: 1:x') y = (sbDiv_emit 0 (-1:x') y) sbDiv' ( 0:x') y = (sbDiv_emit 0 x' y) sbDiv' x@( 1:x') y = case a of { (-1) -> if (a'==1) then (sbDiv_emit 2 (-1:r'') y) else (sbDiv_emit 1 (p 0 (sbSub x (0:y))) y); 0 -> sbDiv_emit 2 r' y; 1 -> if (a'== -1) then (sbDiv_emit 2 (1:r'') y) else (sbDiv_emit 4 (p 0 (sbSub r y)) y)} where r@(a:r'@(a':r'')) = sbSub x y sbDiv' x@(-1:x') y = case a of { 1 -> if (a'== -1) then (sbDiv_emit (-2) (1:r'') y) else (sbDiv_emit (-1) (p 0 (sbAdd x (0:y))) y); 0 -> sbDiv_emit (-2) r' y; (-1) -> if (a'== 1) then (sbDiv_emit (-2) (-1:r'') y) else (sbDiv_emit (-4) (p 0 (sbAdd r y)) y)} where r@(a:r'@(a':r'')) = sbAdd x y -- fixinput' : Auxiliary function used by fixinput. -- Fixes a number so that it always start with a -- non-zero digit. fixinput' :: SBinStream -> Integer -> SBinFloat fixinput' ( 0: x) n = fixinput' x (n+1) fixinput' ( 1: -1: x) n = fixinput' ( 1:x) (n+1) fixinput' (-1: 1: x) n = fixinput' (-1:x) (n+1) fixinput' x n = (n,x) fixinput :: SBinStream -> SBinFloat fixinput x = fixinput' x 0 -- sbfDiv : Top level division function. sbfDiv :: SBinFloat -> SBinFloat -> SBinFloat sbfDiv (ex, mx) (ey,my) = dyfToSbf (dyf (ex-ey+ey_fix+2, sbDiv mx my')) where (ey_fix, my') = fixinput my