2 - Copyright (C) 2009-2010 Nick Bowler.
4 - License BSD2: 2-clause BSD license. See LICENSE for full terms.
5 - This is free software: you are free to change and redistribute it.
6 - There is NO WARRANTY, to the extent permitted by law.
9 -- | Definition of the core floating point types and basic manipulation of
11 {-# LANGUAGE MultiParamTypeClasses, FlexibleInstances, OverlappingInstances #-}
12 {-# LANGUAGE MagicHash #-}
13 module Data
.Floating
.Types
(
14 Double(..), Float(..), FloatConvert
(..)
17 import Prelude
hiding (Double, Float)
18 import qualified GHC
.Exts
as GHC
27 -- | The Double type. This is expected to be an identical declaration to
28 -- the one found in GHC.Prim. We avoid simply using GHC's type because we need
29 -- to define our own class instances.
30 data Double = D
# Double#
33 data Float = F
# Float#
35 -- | This type is identical to CDouble. For some reason unknown to me, it is
36 -- impossible to marshal data from Double to CDouble without losing
37 -- information. The issue is further complicated by Foreign.C.Types not
38 -- exporting CDouble's constructor. Thus, to marshal data from Double to
39 -- CDouble, we construct an instance of this type and then use unsafeCoerce.
40 newtype FuckFFIDouble
= FuckD
Double
42 -- | The analogue of FuckFFIDouble for CFloat.
43 newtype FuckFFIFloat
= FuckF
Float
45 -- | Coercion to floating point types.
46 class FloatConvert a b
where
47 -- | Convert to a floating point type. Conversions from integers and real
48 -- types are provided, as well as conversions between floating point types.
49 -- Conversions between floating point types preserve infinities, negative
53 instance FloatConvert
Double CDouble
where
54 toFloating
= unsafeCoerce
. FuckD
56 instance FloatConvert CDouble
Double where
57 toFloating f
= let FuckD x
= unsafeCoerce f
in x
59 instance FloatConvert
Float CFloat
where
60 toFloating
= unsafeCoerce
. FuckF
62 instance FloatConvert CFloat
Float where
63 toFloating f
= let FuckF x
= unsafeCoerce f
in x
65 instance FloatConvert
Double Float where
66 toFloating
(D
# x
) = F
# (double2Float
# x
)
68 instance FloatConvert
Float Double where
69 toFloating
(F
# x
) = D
# (float2Double
# x
)
71 instance FloatConvert
Integer Double where
72 toFloating x
= D
# (doubleFromInteger x
)
74 instance FloatConvert
Integer Float where
75 toFloating x
= F
# (floatFromInteger x
)
77 instance Real a
=> FloatConvert a
Double where
78 toFloating x
= D
# (num
/## denom
) where
79 !(D
# num
) = toFloating
. numerator . toRational $ x
80 !(D
# denom
) = toFloating
. denominator . toRational $ x
82 instance Real a
=> FloatConvert a
Float where
83 toFloating x
= F
# (divideFloat
# num denom
) where
84 !(F
# num
) = toFloating
. numerator . toRational $ x
85 !(F
# denom
) = toFloating
. denominator . toRational $ x
87 instance FloatConvert a a
where