diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,31 @@
+Copyright (c) 2010, Edward Kmett
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+
+    * Neither the name of Edward Kmett nor the names of other
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/Numeric/Precision/Fixed.hs b/Numeric/Precision/Fixed.hs
new file mode 100644
--- /dev/null
+++ b/Numeric/Precision/Fixed.hs
@@ -0,0 +1,212 @@
+{-# LANGUAGE CPP, ScopedTypeVariables, MagicHash, EmptyDataDecls, FlexibleContexts, MultiParamTypeClasses #-}
+module Numeric.Precision.Fixed 
+    ( Fixed(..)
+    , RoundMode(..)
+    , Near, Zero, Up, Down
+    , Precision
+    , reflectMode
+    , reflectPrecision
+    , fromMPFR
+    , fromInt
+    , fromWord
+    , fromDouble
+    , posInfinity
+    , negInfinity
+    , nan
+    , roundedTowardZero
+    , roundedUp
+    , roundedDown
+    , roundedToNearest
+    ) where
+
+import Data.Tagged
+import Data.Ratio
+import Data.Word
+import Data.Reflection
+#if (__GLASGOW_HASKELL >= 610) && (__GLASGOW_HASKELL__ < 612)
+import GHC.Integer.Internals
+#elif (__GLASGOW_HASKELL__ >= 612)
+import GHC.Integer.GMP.Internals
+#endif
+import GHC.Exts (Int(..)) 
+import Foreign.C.Types
+import Data.Number.MPFR (RoundMode(..), Precision, MPFR)
+import qualified Data.Number.MPFR as M
+
+newtype Fixed r p = Fixed MPFR deriving (Eq,Show,Ord)
+
+data Near
+data Zero
+data Up
+data Down
+
+instance Reifies Near RoundMode where
+    reflect = Tagged Near
+
+instance Reifies Zero RoundMode where
+    reflect = Tagged Zero
+
+instance Reifies Up RoundMode where
+    reflect = Tagged Up
+
+instance Reifies Down RoundMode where
+    reflect = Tagged Down
+
+instance Reifies Float Precision where
+    reflect = floatPrecision
+
+instance Reifies CFloat Precision where
+    reflect = floatPrecision
+
+instance Reifies Double Precision where
+    reflect = floatPrecision
+
+instance Reifies CDouble Precision where
+    reflect = floatPrecision
+
+floatPrecision :: RealFloat a => Tagged a Precision
+floatPrecision = r
+    where 
+        r = Tagged (fromIntegral (floatDigits (undefined `asArg1Of` r)))
+        asArg1Of :: a -> f a b -> a 
+        asArg1Of = const
+
+untagMode :: Tagged r a -> Fixed r p -> a
+untagMode (Tagged t) _ = t
+
+untagPrecision :: Tagged p a -> Fixed r p -> a 
+untagPrecision (Tagged t) _ = t
+
+reflectMode :: Reifies r RoundMode => Fixed r p -> RoundMode
+reflectMode = untagMode reflect
+
+reflectPrecision :: Reifies p Precision => Fixed r p -> Precision
+reflectPrecision = untagPrecision reflect
+
+liftFrom :: 
+    ( Reifies r RoundMode
+    , Reifies p Precision
+    ) => 
+    (RoundMode -> Precision -> a -> MPFR) -> 
+    a -> Fixed r p 
+liftFrom f a = r where r= Fixed $ f (reflectMode r) (reflectPrecision r) a 
+
+fromMPFR :: (Reifies r RoundMode, Reifies p Precision) => MPFR -> Fixed r p 
+fromMPFR = liftFrom M.set
+
+fromInt :: (Reifies r RoundMode, Reifies p Precision) => Int -> Fixed r p 
+fromInt = liftFrom M.fromInt
+
+fromWord :: (Reifies r RoundMode, Reifies p Precision) => Word -> Fixed r p 
+fromWord = liftFrom M.fromWord
+
+fromDouble :: (Reifies r RoundMode, Reifies p Precision) => Double -> Fixed r p 
+fromDouble = liftFrom M.fromDouble
+
+posInfinity :: (Reifies r RoundMode, Reifies p Precision) => Fixed r p
+posInfinity = liftFrom (const M.setInf) 1
+
+negInfinity :: (Reifies r RoundMode, Reifies p Precision) => Fixed r p
+negInfinity = liftFrom (const M.setInf) (-1)
+
+nan :: (Reifies p Precision) => Fixed r p
+nan = r where r = Fixed $ M.setNaN (reflectPrecision r)
+
+lift0 ::
+    ( Reifies r RoundMode
+    , Reifies p Precision
+    ) => 
+    (RoundMode -> Precision -> MPFR) -> 
+    Fixed r p
+lift0 f = r where r = Fixed $ f (reflectMode r) (reflectPrecision r)
+
+lift1 :: 
+    ( Reifies r RoundMode
+    , Reifies p Precision
+    ) => 
+    (RoundMode -> Precision -> MPFR -> MPFR) -> 
+    Fixed r p -> Fixed r p
+lift1 f i@(Fixed a) = Fixed $ f (reflectMode i) (reflectPrecision i) a
+
+lift2 :: 
+    ( Reifies r RoundMode
+    , Reifies p Precision
+    ) => 
+    (RoundMode -> Precision -> MPFR -> MPFR -> MPFR) -> 
+    Fixed r p -> Fixed r p -> Fixed r p
+lift2 f i@(Fixed a) (Fixed b) = Fixed $ f (reflectMode i) (reflectPrecision i) a b
+
+roundedTowardZero :: Reifies p Precision => Fixed Zero p -> Fixed r p
+roundedTowardZero (Fixed a) = Fixed a
+
+roundedUp :: Reifies p Precision => Fixed Up p -> Fixed r p
+roundedUp (Fixed a) = Fixed a
+
+roundedDown :: Reifies p Precision => Fixed Down p -> Fixed r p
+roundedDown (Fixed a) = Fixed a
+
+roundedToNearest :: Reifies p Precision => Fixed Near p -> Fixed r p
+roundedToNearest (Fixed a) = Fixed a
+
+instance (Reifies r RoundMode, Reifies p Precision) => Num (Fixed r p) where
+    (+)    = lift2 M.add
+    (-)    = lift2 M.sub
+    (*)    = lift2 M.mul
+    negate = lift1 M.neg
+    abs    = lift1 M.absD
+    signum = undefined -- TODO
+    fromInteger (S# i) = fromInt (I# i)
+    fromInteger i = roundedTowardZero (liftFrom M.fromIntegerA i)
+
+instance (Reifies r RoundMode, Reifies p Precision) => Real (Fixed r p) where
+    toRational (Fixed d) = n % 2 ^ e
+        where (n' , e') = M.decompose d
+              (n, e) | e' >= 0 = ((n' * 2 ^ e'), 0)
+                     | otherwise = (n', - e')
+
+instance (Reifies r RoundMode, Reifies p Precision) => Fractional (Fixed r p) where
+    (/) = lift2 M.div
+    fromRational r = fromInteger (numerator r) / fromInteger (denominator r)
+    recip d = Fixed M.one / d
+
+instance (Reifies r RoundMode, Reifies p Precision) => Floating (Fixed r p) where
+    pi = lift0 M.pi
+    exp = lift1 M.exp
+    log = lift1 M.log
+    sqrt = lift1 M.sqrt
+    (**) = lift2 M.pow
+    
+    sin = lift1 M.sin
+    cos = lift1 M.cos
+    tan = lift1 M.tan
+    asin = lift1 M.asin
+    acos = lift1 M.acos
+    atan = lift1 M.atan
+    sinh = lift1 M.sinh
+    cosh = lift1 M.cosh
+    tanh = lift1 M.tanh
+    asinh = lift1 M.asinh
+    acosh = lift1 M.acosh
+    atanh = lift1 M.atanh
+
+instance (Reifies r RoundMode, Reifies p Precision) => RealFrac (Fixed r p) where
+    properFraction fp@(Fixed d) = (fromIntegral n, Fixed f)
+        where r = toRational fp
+              m = numerator r
+              e = denominator r
+              n = quot m e
+              f = M.frac Down (M.getPrec d) d
+
+{-
+instance (Reifies r RoundMode, Reifies p Precision) => RealFloat (Fixed r p) where
+    floatRadix _ = 2
+    floatRange _ = (minBound, maxBound)
+    floatDigits p = fromIntegral (reflectPrecision p)
+    decodeFloat (Fixed d) = (m, fromIntegral e)
+        where
+            (m,e) = M.decompose d
+    -- a whole bunch of other methods
+-}
+    
+
+-- withPrecision :: Precision -> (forall p. Reifies p Precision => Fixed r p) -> 
diff --git a/Setup.lhs b/Setup.lhs
new file mode 100644
--- /dev/null
+++ b/Setup.lhs
@@ -0,0 +1,3 @@
+#!/usr/bin/env runhaskell
+> import Distribution.Simple
+> main = defaultMainWithHooks simpleUserHooks
diff --git a/fixed-precision.cabal b/fixed-precision.cabal
new file mode 100644
--- /dev/null
+++ b/fixed-precision.cabal
@@ -0,0 +1,25 @@
+Name:              fixed-precision
+Version:           0.2.0
+Synopsis:          Fixed Precision Arithmetic
+Description:
+    Numeric instances for MPFR that use the \"Implicit Configurations\" from 
+    <http://www.cs.rutgers.edu/~ccshan/prepose/prepose.pdf>
+    to choose 'Rounding' and 'Precision'.
+Homepage:          http://patch-tag.com/r/ekmett/fixed-precision
+License:           BSD3
+License-file:      LICENSE
+Author:            Edward Kmett
+Maintainer:        ekmett@gmail.com
+Category:          Math
+Build-type:        Simple
+Cabal-version:     >=1.6
+
+Library
+  Exposed-modules: Numeric.Precision.Fixed
+  Build-depends:   base >= 4 && < 5,
+                   reflection >= 0.3.0 && < 0.4,
+                   hmpfr >= 0.3.1 && < 0.4,
+                   integer-gmp >= 0.2.0 && < 0.3,
+                   tagged >= 0.0 && < 0.1
+  GHC-Options:     -Wall
+    
