module CombinatorialOptimisation.TSP.FixedPoint (FP(FP),unwrappedFP,doubleToFP,fpToDouble) where
import Data.Int
import Data.Bits
import Data.Ratio
import Foreign.C.Types
fixedPoint = 32
divConstI = 2^fromIntegral fixedPoint
divConstD = 2**fromIntegral fixedPoint
divConstC :: CDouble
divConstC = fromIntegral divConstI
fpOne = fromInteger 1
newtype FP = FP Int64 deriving (Eq,Ord)
instance Show FP where
show x@(FP a) = "FP internal:"++(show a)++" floating:"++(show . (realToFrac :: FP->Double) $ x)
instance Num FP where
(+) (FP a) (FP b) = FP (a+b)
(*) (FP a) (FP b) = FP $ fromIntegral $ shiftR ((toInteger a) * (toInteger b)) fixedPoint
() (FP a) (FP b) = FP (ab)
negate (FP a) = FP (a)
abs (FP a) = FP (abs a)
signum (FP a) = FP (signum a)
fromInteger i = FP (shiftL (fromInteger i) fixedPoint)
instance Fractional FP where
(/) (FP a) (FP b) = FP $ fromInteger (div (shiftL (toInteger a) fixedPoint) (toInteger b))
recip = (/) fpOne
fromRational = doubleToFP . fromRational
instance Real FP where
toRational (FP a) = (fromIntegral a) % divConstI
fpToDouble :: FP->Double
fpToDouble (FP x) = realToFrac (fromIntegral x / divConstC)
doubleToFP :: Double->FP
doubleToFP = FP . unwrappedFP
unwrappedFP :: Double->Int64
unwrappedFP x = let (a,b) = properFraction x
in (shiftL (fromInteger a) fixedPoint) + (floor (b * divConstD))
five,six :: FP
five = fromInteger 5
six = fromInteger 6