module BasicNumberApprox (equ, lt, gt, lte, gte, ne, rabs, rsignum,
rtoRational, basicNumber2str) where
import RealM
import BasicNumber
import Ratio--1.3
import List(genericDrop, genericTake)--1.3
-- This module contains a set of routines which need a precision
-- argument to work for reals. For example, two real numbers can
-- be compared for equality only to a cerain precision.
-- Compare a and b for equality to a precision n.
equ :: BasicNumber -> BasicNumber -> Integer -> Bool
equ (BasRealC a) b n = if (diff <= 2) then True
else False
where
diff = abs ((evalReal a n) - (evalReal c n))
(BasRealC c) = makeReal b
equ a (b@(BasRealC _)) n = equ b a n
equ a b _ = a == b
-------------------------------------------------------------------------------
-- Check if a < b to a precision n.
lt :: BasicNumber -> BasicNumber -> Integer -> Bool
lt (BasRealC a) b n = if (diff < -2) then True
else False
where
diff = ((evalReal a n) - (evalReal c n))
(BasRealC c) = makeReal b
lt a (b@(BasRealC _)) n = gt b a n
lt a b _ = a < b
-------------------------------------------------------------------------------
-- Check if a > b to a precision n.
gt :: BasicNumber -> BasicNumber -> Integer -> Bool
gt (BasRealC a) b n = if (diff > 2) then True
else False
where
diff = ((evalReal a n) - (evalReal c n))
(BasRealC c) = makeReal b
gt a (b@(BasRealC _)) n = lt b a n
gt a b _ = b < a
-------------------------------------------------------------------------------
-- Check if a <= b to a precision n.
lte :: BasicNumber -> BasicNumber -> Integer -> Bool
lte a b n = not (gt a b n)
-------------------------------------------------------------------------------
-- Check if a >= b to a precision n.
gte :: BasicNumber -> BasicNumber -> Integer -> Bool
gte a b n = not (lt a b n)
-------------------------------------------------------------------------------
-- Check if a /= b to a precision n.
ne :: BasicNumber -> BasicNumber -> Integer -> Bool
ne a b n = not (equ a b n)
-------------------------------------------------------------------------------
-- Get the absolute value of a.
rabs :: BasicNumber -> Integer -> BasicNumber
rabs (a@(BasRealC ar)) n = if (evalReal ar n) < 0 then (fromInteger(-1))*a
else a
rabs a n = abs a
-------------------------------------------------------------------------------
-- Get the sign of a number.
rsignum :: BasicNumber -> Integer -> BasicNumber
rsignum (a@(BasRealC ar)) n = if ev_ar < 0
then fromInteger (-1)
else if ev_ar == 0
then fromInteger 0
else fromInteger 1
where
ev_ar = evalReal ar n
rsignum a n = signum a
-------------------------------------------------------------------------------
-- Convert a BasicNumber to a rational with precision n.
rtoRational :: BasicNumber -> Integer -> BasicNumber
rtoRational (BasRealC a) n = if n <= 0
then (BasRationalC ((evalReal a n) % (10^(-n))))
else (BasRationalC (((evalReal a n)*(10^n)) % 1))
rtoRational a _ = makeRational a
-------------------------------------------------------------------------------
-- Convert a BasicNumber to a string with precision n.
basicNumber2str :: BasicNumber -> Integer -> String
basicNumber2str (BasRealC x) prec =
intPart ++ "." ++ fracPart
where
evalX = show (evalReal x prec)
lenBeforeDecimal = (toInteger (length evalX))
+ prec
intPart = if lenBeforeDecimal <= 0
then "0"
else genericTake lenBeforeDecimal
evalX
fracPart = if lenBeforeDecimal < 0
then (pad (- lenBeforeDecimal)
'0') ++
evalX
else genericDrop lenBeforeDecimal
evalX
pad 0 a = []
--WAS:pad (n+1) a = a:(pad n a)
pad n a = a:(pad (n-1) a)
basicNumber2str (BasRationalC x) _ = show x
basicNumber2str (BasIntegerC x) _ = show x
-------------------------------------------------------------------------------
|