AERN-Real-Double-2011.1: src/Numeric/AERN/RealArithmetic/Basis/Double/Conversion.hs
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeSynonymInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-|
Module : Numeric.AERN.RealArithmetic.Basis.Double.Conversion
Description : conversions between Double and standard numeric types
Copyright : (c) Michal Konecny
License : BSD3
Maintainer : mikkonecny@gmail.com
Stability : experimental
Portability : portable
Conversions between Double and standard numeric types.
This is a private module reexported publicly via its parent.
-}
module Numeric.AERN.RealArithmetic.Basis.Double.Conversion where
import Numeric.AERN.RealArithmetic.NumericOrderRounding
import Numeric.AERN.Basics.Exception
import Control.Exception
instance Convertible Integer Double where
type ConvertEffortIndicator Integer Double = ()
convertDefaultEffort _ _ = ()
convertUpEff _ n
| ndn >= n = Just dn
| otherwise = Just dnUp
where
dn = fromInteger n
ndn = floor dn
(m, e) = decodeFloat dn
dnUp = encodeFloat (m + 1) e
convertDnEff _ n
| ndn <= n = Just dn
| otherwise = Just dnDn
where
dn = fromInteger n
ndn = ceiling dn
(m, e) = decodeFloat dn
dnDn = encodeFloat (m - 1) e
instance Convertible Int Double where
type ConvertEffortIndicator Int Double = ()
convertDefaultEffort _ _ = ()
convertUpEff effort n =
convertUpEff effort (toInteger n)
convertDnEff effort n =
convertDnEff effort (toInteger n)
instance Convertible Double Integer where
type ConvertEffortIndicator Double Integer = ()
convertDefaultEffort _ _ = ()
convertUpEff _ d
| isInfinite d = Nothing
| otherwise = Just $ ceiling d
convertDnEff _ d
| isInfinite d = Nothing
| otherwise = Just $ floor d
instance Convertible Double Int where
type ConvertEffortIndicator Double Int = ()
convertDefaultEffort _ _ = ()
convertUpEff effort d =
case mdUpInteger of
Nothing -> Nothing
Just dUpInteger
| dUpInteger > (toInteger intMax) -> Nothing
| otherwise -> Just $ fromInteger dUpInteger
where
mdUpInteger = convertUpEff effort d
intMax = maxBound :: Int
convertDnEff effort d =
case mdDnInteger of
Nothing -> Nothing
Just dDnInteger
| dDnInteger < (toInteger intMin) -> Nothing
| otherwise -> Just $ fromInteger dDnInteger
where
mdDnInteger = convertDnEff effort d
intMin = minBound :: Int
instance Convertible Double Double where
type ConvertEffortIndicator Double Double = ()
convertDefaultEffort _ _ = ()
convertUpEff _ d = Just d
convertDnEff _ d = Just d
instance Convertible Rational Double where
type ConvertEffortIndicator Rational Double = ()
convertDefaultEffort _ _ = ()
convertUpEff _ r
| rdr >= r = Just dr
| otherwise = Just drUp
where
rdr = toRational dr
dr = fromRational r
(m, e) = decodeFloat dr
drUp = encodeFloat (m + 1) e
convertDnEff _ r
| rdr <= r = Just dr
| otherwise = Just drDn
where
rdr = toRational dr
dr = fromRational r
(m, e) = decodeFloat dr
drDn = encodeFloat (m - 1) e
instance Convertible Double Rational where
type ConvertEffortIndicator Double Rational = ()
convertDefaultEffort _ _ = ()
convertUpEff _ d
| isInfinite d = Nothing
| otherwise = Just $ toRational d
convertDnEff eff d = convertUpEff eff d