diff --git a/Data/Number/MPFR/Arithmetic.hs b/Data/Number/MPFR/Arithmetic.hs
--- a/Data/Number/MPFR/Arithmetic.hs
+++ b/Data/Number/MPFR/Arithmetic.hs
@@ -19,11 +19,11 @@
 import Data.Number.MPFR.Internal
 
 add           :: RoundMode -> Precision -> MPFR -> MPFR -> MPFR
-add r p d1 d2 = fst $ add_ r p d1 d2 
+add r p d1 d2 = fst $ add_ r p d1 d2
       
 addw          :: RoundMode -> Precision -> MPFR -> Word -> MPFR
 addw r p d1 d = fst $ addw_ r p d1 d 
-      
+
 addi          :: RoundMode -> Precision -> MPFR -> Int -> MPFR
 addi r p d1 d = fst $ addi_ r p d1 d 
       
@@ -122,7 +122,7 @@
       
 addw_          :: RoundMode -> Precision -> MPFR -> Word -> (MPFR, Int)
 addw_ r p d1 d = withMPFRBAui r p d1 (fromIntegral d) mpfr_add_ui
-      
+
 addi_          :: RoundMode -> Precision -> MPFR -> Int -> (MPFR, Int)
 addi_ r p d1 d = withMPFRBAsi r p d1 (fromIntegral d) mpfr_add_si
       
@@ -140,7 +140,7 @@
       
 isub_          :: RoundMode -> Precision -> Int -> MPFR -> (MPFR, Int)
 isub_ r p d d1 = withMPFRBAis r p (fromIntegral d) d1 mpfr_si_sub
-      
+
 mul_           :: RoundMode -> Precision -> MPFR -> MPFR -> (MPFR,Int)
 mul_ r p d1 d2 =  withMPFRsBA r p d1 d2 mpfr_mul
       
diff --git a/Data/Number/MPFR/Comparison.hs b/Data/Number/MPFR/Comparison.hs
--- a/Data/Number/MPFR/Comparison.hs
+++ b/Data/Number/MPFR/Comparison.hs
@@ -72,16 +72,16 @@
                    else Just (compare (withMPFRBB mp1 mp2 mpfr_cmpabs) 0)
 
 isNaN   :: MPFR -> Bool
-isNaN d = withMPFRB d mpfr_nan_p /= 0
+isNaN (MP _ _ e _) = e == expNaN -- withMPFRB d mpfr_nan_p /= 0
 
 isInfinite   :: MPFR -> Bool
-isInfinite d = withMPFRB d mpfr_inf_p /= 0 
+isInfinite (MP _ _ e _) = e == expInf -- withMPFRB d mpfr_inf_p /= 0 
 
 isNumber   :: MPFR -> Bool
 isNumber d = withMPFRB d mpfr_number_p /= 0 
 
 isZero   :: MPFR -> Bool
-isZero d = withMPFRB d mpfr_zero_p /= 0
+isZero (MP _ _ e _) = e == expZero --withMPFRB d mpfr_zero_p /= 0
 
 sgn     :: MPFR -> Maybe Int 
 sgn mp1 = case (cmpw mp1 0) of
diff --git a/Data/Number/MPFR/Conversion.hs b/Data/Number/MPFR/Conversion.hs
--- a/Data/Number/MPFR/Conversion.hs
+++ b/Data/Number/MPFR/Conversion.hs
@@ -76,7 +76,12 @@
 
 -- TODO
 decompose   :: MPFR -> (Integer, Exp)
-decompose d = (getMantissa d, getExp d - fromIntegral (Prelude.ceiling (fromIntegral (getPrec d) / fromIntegral bitsPerMPLimb :: Double) * bitsPerMPLimb))
+decompose d@(MP p _ e _) | e == expInf  = error "Don't know how to decompose Infinity"
+                         | e == expNaN  = error "Don't know how to decompose NaN"
+                         | e == expZero = (0, 0) 
+                         | otherwise    = (dm, e - sh)
+    where dm = getMantissa d
+          sh =  fromIntegral (Prelude.ceiling (fromIntegral p / fromIntegral bitsPerMPLimb :: Double) * bitsPerMPLimb)
 
 -- | Output a string in base 10 rounded to Near in exponential form.
 toStringExp       :: Word -- ^ number of digits
diff --git a/Data/Number/MPFR/FFIhelper.hsc b/Data/Number/MPFR/FFIhelper.hsc
--- a/Data/Number/MPFR/FFIhelper.hsc
+++ b/Data/Number/MPFR/FFIhelper.hsc
@@ -25,7 +25,7 @@
     fromEnum Up          = #{const GMP_RNDU} 
     fromEnum Down        = #{const GMP_RNDD} 
     fromEnum GMP_RND_MAX = #{const GMP_RND_MAX}
-    fromEnum GMP_RNDNA    = #{const GMP_RNDNA}
+    fromEnum GMP_RNDNA   = #{const GMP_RNDNA}
     
     toEnum #{const GMP_RNDN}    = Near
     toEnum #{const GMP_RNDZ}    = Zero
@@ -36,10 +36,10 @@
     toEnum i                    = error $ "RoundMode.toEnum called with illegal argument :" ++ show i 
 
 
-data MPFR = MP { precision :: !CPrecision,
-                 sign :: !Sign,
-                 exponent :: !Exp,
-                 limbs :: !(ForeignPtr Limb)
+data MPFR = MP { precision :: {-# UNPACK #-} !CPrecision,
+                 sign :: {-# UNPACK #-} !Sign,
+                 exponent :: {-# UNPACK #-} !Exp,
+                 limbs :: {-# UNPACK #-} !(ForeignPtr Limb)
 } deriving (Typeable)
 
 instance Storable MPFR where
@@ -53,8 +53,8 @@
 {-# INLINE peekP #-}
 peekP      :: Ptr MPFR -> ForeignPtr Limb -> IO MPFR
 peekP p fp = do r11 <- #{peek __mpfr_struct, _mpfr_prec} p
-	        r21 <- #{peek __mpfr_struct, _mpfr_sign} p
-		r22 <- #{peek __mpfr_struct, _mpfr_exp} p
+                r21 <- #{peek __mpfr_struct, _mpfr_sign} p
+                r22 <- #{peek __mpfr_struct, _mpfr_exp} p
                 return (MP r11 r21 r22 fp)
 {-# INLINE withDummy #-}
 withDummy     :: Word -> (Ptr MPFR -> IO CInt) -> IO (MPFR, Int)
@@ -69,6 +69,7 @@
                       r1 <- peekP ptr fp
                       return (r1, fromIntegral r2)
 
+{-# INLINE pokeDummy #-}
 pokeDummy          :: Ptr MPFR -> ForeignPtr Limb -> Word -> IO ()
 pokeDummy ptr fp p = do #{poke __mpfr_struct, _mpfr_prec} ptr (fromIntegral p :: CPrecision)
                         #{poke __mpfr_struct, _mpfr_sign} ptr (0 :: Sign) 
@@ -77,6 +78,16 @@
 
 bitsPerMPLimb :: Int 
 bitsPerMPLimb = 8 * #size mp_limb_t
+
+expZero :: Exp
+expZero = #const __MPFR_EXP_ZERO
+
+expNaN :: Exp
+expNaN = #const __MPFR_EXP_NAN
+
+expInf :: Exp
+expInf = #const __MPFR_EXP_INF
+
 
 type CRoundMode = CInt
 
diff --git a/Data/Number/MPFR/Internal.hs b/Data/Number/MPFR/Internal.hs
--- a/Data/Number/MPFR/Internal.hs
+++ b/Data/Number/MPFR/Internal.hs
@@ -54,8 +54,8 @@
                               -> (Ptr MPFR -> Ptr MPFR -> CLong -> CRoundMode -> IO CInt)
                               -> (MPFR, Int)
 withMPFRBAsi r p !mp1 d f = unsafePerformIO go 
-    where go = do withDummy p $ \p1 -> do
-                    with mp1 $ \p2 -> do
+    where go = do withDummy p $ \ p1 -> do
+                    with mp1 $ \ p2 -> do
                       f p1 p2 d ((fromIntegral . fromEnum) r)
                                   
 {-# INLINE withMPFRBAiu #-}
@@ -78,11 +78,11 @@
                      
 {-# INLINE withMPFRB #-}
 withMPFRB       :: MPFR -> (Ptr MPFR -> IO CInt) -> CInt 
-withMPFRB mp1 !f = unsafePerformIO go
+withMPFRB !mp1 f = unsafePerformIO go
     where go = with mp1 $ \p1 -> f p1
 
 withMPFRP       :: MPFR -> (Ptr MPFR -> IO CPrecision) -> CPrecision 
-withMPFRP mp1 !f = unsafePerformIO go
+withMPFRP !mp1 f = unsafePerformIO go
     where go = with mp1 $ \p1 -> f p1
 
 {-# INLINE withMPFR #-}
@@ -98,7 +98,7 @@
 withMPFRBB           :: MPFR -> MPFR 
                           -> (Ptr MPFR -> Ptr MPFR -> IO CInt) 
                           -> CInt  
-withMPFRBB mp1 mp2 f = unsafePerformIO go
+withMPFRBB !mp1 !mp2 f = unsafePerformIO go
     where go = do with mp1 $ \p1 -> do 
                     with mp2 $ \p2 -> do 
                                       f p1 p2
@@ -128,7 +128,7 @@
 withMPFRR       :: Precision -> MPFR
                      -> (Ptr MPFR -> Ptr MPFR -> IO CInt)
                      -> (MPFR, Int)
-withMPFRR p d f = unsafePerformIO go
+withMPFRR p !d f = unsafePerformIO go
     where go = do withDummy p $ \p1 -> do
                     with d $ \p2 -> do
                       f p1 p2
diff --git a/Data/Number/MPFR/Misc.hs b/Data/Number/MPFR/Misc.hs
--- a/Data/Number/MPFR/Misc.hs
+++ b/Data/Number/MPFR/Misc.hs
@@ -19,6 +19,7 @@
 
 import Data.Number.MPFR.Assignment
 
+import Data.List(foldl')
 
 nextToward         :: MPFR -> MPFR -> MPFR
 nextToward mp1 mp2 = unsafePerformIO go
@@ -98,14 +99,19 @@
 minD_ r p d1 d2 = withMPFRsBA r p d1 d2 mpfr_min
 
 getPrec   :: MPFR -> Precision
-getPrec d = fromIntegral (withMPFRP d mpfr_get_prec)
+getPrec (MP p _ _ _) = fromIntegral p -- fromIntegral (withMPFRP d mpfr_get_prec)
 
 -- | getMantissa and getExp return values such that
 --
--- > d = getMantissa d * 2^(getExp d - Prelude.ceiling ((getPrec d) / bitsPerMPLimb)* bitsPerMPLimb )
+-- > d = getMantissa d * 2^(getExp d - ceiling ((getPrec d) / bitsPerMPLimb)* bitsPerMPLimb )
+--
+-- If case of 0, NaN or +-Inf it will return 0
 getMantissa   :: MPFR -> Integer
-getMantissa d = toInteger (sign d) * h
-               where (h, _) = foldl (\(a,b) c -> (a + (toInteger c) `shiftL` b, b + bitsPerMPLimb)) (0,0) (getMantissa' d) 
+getMantissa d@(MP _ s e _) | e /= expInf && e /= expNaN && e /= expZero = toInteger s * h
+                           | otherwise                                  = 0
+    where (h, _) = foldl' (\(a,b) c ->
+                               (a + (toInteger c) `shiftL` b, b + bitsPerMPLimb))
+                   (0,0) (getMantissa' d) 
 
 one :: MPFR
 one = fromWord Near minPrec 1
diff --git a/hmpfr.cabal b/hmpfr.cabal
--- a/hmpfr.cabal
+++ b/hmpfr.cabal
@@ -1,5 +1,5 @@
 name:                hmpfr
-version:             0.1.1
+version:             0.1.2
 synopsis:            Haskell binding to MPFR library
 description:         Haskell binding to MPFR library. Tested with MPFR 2.3.1 and 2.3.2.
 		     Some simple examples of usage can be found in test/Demo.hs.
@@ -7,7 +7,7 @@
 license:             BSD3
 license-file:        LICENSE
 Stability:           experimental
-tested-with:	     GHC == 6.8.2 GHC == 6.8.3
+tested-with:	     GHC == 6.8.3
 author:              Aleš Bizjak
 maintainer:          Aleš Bizjak <ales.bizjak0@gmail.com>
 Homepage:	     http://code.haskell.org/hmpfr/
@@ -39,7 +39,7 @@
 
 build-type:          Simple
 build-tools:         hsc2hs
-GHC-options:         -Wall -fno-warn-orphans -O2 -fvia-C -optc-O2
+GHC-options:         -Wall -fno-warn-orphans -O2 -funfolding-keeness-factor=10 -fvia-C -optc-O2
 GHC-prof-options:    -prof -auto-all
 include-dirs:        cbits
 includes:            chsmpfr.h mpfr.h
diff --git a/test/Demo.hs b/test/Demo.hs
--- a/test/Demo.hs
+++ b/test/Demo.hs
@@ -1,6 +1,6 @@
 module Demo where
 
-import qualified Data.Number.MPFR as M
+import qualified Data.Number.MPFR.Up as M
 
 -- compute the sum from 1 to n with precision of p bits rounded to Near
 s     :: M.Precision -> Int -> M.MPFR
@@ -10,6 +10,9 @@
 
 s'    :: M.Precision -> Int -> M.MPFR
 s' p  = foldl (M.addi M.Near p) 0 . enumFromTo 1
+
+s'' :: M.Precision -> Int -> M.MPFR
+s'' p = foldl ((. M.fromInt M.Up p) . (+)) M.zero . enumFromTo 1
 
 -- compute pi with precision of n bits
 pi' n = M.pi M.Near n
