diff --git a/changelog b/changelog
--- a/changelog
+++ b/changelog
@@ -1,6 +1,13 @@
+0.3.3.0
+	* Add the isFloating or isInteger predicates.
+	  Courtesy of Zejun Wu (@watashi).
+	* Add the toRealFloat' and toBoundedInteger functions.
+	  Courtesy of Fujimura Daisuke (@fujimura).
+
 0.3.2.2
 	* Enable package to link with integer-simple instead of
 	  integer-gmp using the -finteger-simple cabal flag.
+	  Courtesy of @k0ral.
 
 0.3.2.1
 
diff --git a/scientific.cabal b/scientific.cabal
--- a/scientific.cabal
+++ b/scientific.cabal
@@ -1,5 +1,5 @@
 name:                scientific
-version:             0.3.2.2
+version:             0.3.3.0
 synopsis:            Numbers represented using scientific notation
 description:
   @Data.Scientific@ provides a space efficient and arbitrary precision
@@ -95,6 +95,7 @@
                , base             >= 4.3   && < 4.8
                , tasty            >= 0.5   && < 0.9
                , tasty-ant-xml    >= 1.0   && < 1.1
+               , tasty-hunit      >= 0.8   && < 0.9
                , tasty-smallcheck >= 0.2   && < 0.9
                , tasty-quickcheck >= 0.8   && < 0.9
                , smallcheck       >= 1.0   && < 1.2
diff --git a/src/Data/Scientific.hs b/src/Data/Scientific.hs
--- a/src/Data/Scientific.hs
+++ b/src/Data/Scientific.hs
@@ -38,6 +38,12 @@
 -- to @'Integral's@ (like: 'Int') or @'RealFloat's@ (like: 'Double' or 'Float')
 -- will always be bounded by the target type.
 --
+-- /WARNING:/ Although @Scientific@ is an instance of 'Fractional', the methods
+-- are only partially defined! Specifically 'recip' and '/' will diverge
+-- (i.e. loop and consume all space) when their outputs have an infinite decimal
+-- expansion. 'fromRational' will diverge when the input 'Rational' has an
+-- infinite decimal expansion.
+--
 -- This module is designed to be imported qualified:
 --
 -- @import Data.Scientific as Scientific@
@@ -51,10 +57,16 @@
     , coefficient
     , base10Exponent
 
+      -- * Predicates
+    , isFloating
+    , isInteger
+
       -- * Conversions
-    , fromFloatDigits
-    , toRealFloat
     , floatingOrInteger
+    , toRealFloat
+    , toBoundedRealFloat
+    , toBoundedInteger
+    , fromFloatDigits
 
       -- * Pretty printing
     , formatScientific
@@ -216,9 +228,9 @@
   "realToFrac_toRealFloat_Float"
    realToFrac = toRealFloat :: Scientific -> Float #-}
 
--- | /WARNING:/ 'recip' and '/' will diverge when their outputs have
--- an infinite decimal expansion. 'fromRational' will diverge when the
--- input 'Rational' has an infinite decimal expansion.
+-- | /WARNING:/ 'recip' and '/' will diverge (i.e. loop and consume all space)
+-- when their outputs have an infinite decimal expansion. 'fromRational' will
+-- diverge when the input 'Rational' has an infinite decimal expansion.
 instance Fractional Scientific where
     recip = fromRational . recip . toRational
     {-# INLINE recip #-}
@@ -326,7 +338,7 @@
 -- space usage is bounded by the target type.
 --
 -- For large negative exponents we check if the exponent is smaller
--- than some limit (currently -1100). In that case we know that the
+-- than some limit (currently -324). In that case we know that the
 -- scientific number is really small (unless the coefficient has many
 -- digits) so we can immediately return -1 for negative scientific
 -- numbers or 0 for positive numbers.
@@ -422,21 +434,29 @@
           go []     !c !n = Scientific c (e - n)
           go (d:ds) !c !n = go ds (c * 10 + fromIntegral d) (n + 1)
 
--- | Convert a 'Scientific' number into a 'RealFloat' (like a 'Double'
--- or a 'Float').
+-- | Safely convert a 'Scientific' number into a 'RealFloat' (like a 'Double' or a
+-- 'Float').
 --
--- Note that this function uses 'realToFrac'
--- (@'fromRational' . 'toRational'@) internally but it guards against
--- computing huge Integer magnitudes (@10^e@) that could fill up all
--- space and crash your program.
+-- Note that this function uses 'realToFrac' (@'fromRational' . 'toRational'@)
+-- internally but it guards against computing huge Integer magnitudes (@10^e@)
+-- that could fill up all space and crash your program. If the 'base10Exponent'
+-- of the given 'Scientific' is too big or too small to be represented in the
+-- target type, Infinity or 0 will be returned respectively. Use
+-- 'toBoundedRealFloat' which explicitly handles this case by returning 'Left'.
 --
--- Always prefer 'toRealFloat' over 'realToFrac' when converting from
--- scientific numbers coming from an untrusted source.
-toRealFloat :: forall a. (RealFloat a) => Scientific -> a
-toRealFloat s@(Scientific c e)
-    | e >  limit && e > hiLimit                    = sign (1/0) -- Infinity
-    | e < -limit && e < loLimit && e + d < loLimit = sign 0
-    | otherwise                                    = realToFrac s
+-- Always prefer 'toRealFloat' over 'realToFrac' when converting from scientific
+-- numbers coming from an untrusted source.
+toRealFloat :: (RealFloat a) => Scientific -> a
+toRealFloat = either id id . toBoundedRealFloat
+
+-- | Preciser version of `toRealFloat`. If the 'base10Exponent' of the given
+-- 'Scientific' is too big or too small to be represented in the target type,
+-- Infinity or 0 will be returned as 'Left'.
+toBoundedRealFloat :: forall a. (RealFloat a) => Scientific -> Either a a
+toBoundedRealFloat s@(Scientific c e)
+    | e >  limit && e > hiLimit                    = Left  $ sign (1/0) -- Infinity
+    | e < -limit && e < loLimit && e + d < loLimit = Left  $ sign 0
+    | otherwise                                    = Right $ realToFrac s
   where
     (loLimit, hiLimit) = exponentLimits (undefined :: a)
 
@@ -459,9 +479,44 @@
       digits   = floatDigits (undefined :: a)
       (lo, hi) = floatRange  (undefined :: a)
 
+-- | Convert a `Scientific` to a bounded integer.
+--
+-- If the given `Scientific` doesn't fit in the target representation, it will
+-- return `Nothing`.
+--
+-- This function also guards against computing huge Integer magnitudes (@10^e@)
+-- that could fill up all space and crash your program.
+toBoundedInteger :: forall i. (Integral i, Bounded i) => Scientific -> Maybe i
+toBoundedInteger s
+    | integral  = if dangerouslyBig
+                  then Nothing
+                  else if n < toInteger (minBound :: i) ||
+                          n > toInteger (maxBound :: i)
+                       then Nothing
+                       else Just $ fromInteger n
+    | otherwise = Nothing
+  where
+    integral = e >= 0 || e' >= 0
+
+    e  = base10Exponent s
+    e' = base10Exponent s'
+
+    s' = normalize s
+
+    dangerouslyBig = e > limit &&
+                     e > integerLog10' (max (abs $ toInteger (minBound :: i))
+                                            (abs $ toInteger (maxBound :: i)))
+
+    -- This should not be evaluated if the given Scientific is dangerouslyBig
+    -- since it could consume all space and crash the process:
+    n :: Integer
+    n = toIntegral s'
+
 -- | @floatingOrInteger@ determines if the scientific is floating point
 -- or integer. In case it's floating-point the scientific is converted
 -- to the desired 'RealFloat' using 'toRealFloat'.
+--
+-- Also see: 'isFloating' or 'isInteger'.
 floatingOrInteger :: (RealFloat r, Integral i) => Scientific -> Either r i
 floatingOrInteger s
     | base10Exponent s  >= 0 = Right (toIntegral   s)
@@ -472,6 +527,26 @@
 
 
 ----------------------------------------------------------------------
+-- Predicates
+----------------------------------------------------------------------
+
+-- | Return 'True' if the scientific is a floating point, 'False' otherwise.
+--
+-- Also see: 'floatingOrInteger'.
+isFloating :: Scientific -> Bool
+isFloating = not . isInteger
+
+-- | Return 'True' if the scientific is an integer, 'False' otherwise.
+--
+-- Also see: 'floatingOrInteger'.
+isInteger :: Scientific -> Bool
+isInteger s = base10Exponent s  >= 0 ||
+              base10Exponent s' >= 0
+  where
+    s' = normalize s
+
+
+----------------------------------------------------------------------
 -- Parsing
 ----------------------------------------------------------------------
 
@@ -640,13 +715,10 @@
 --
 -- then
 --
---      (1) @n >= 1@
---
---      (2) @x = 0.d1d2...dn * (10^^e)@
---
---      (3) @0 <= di <= 9@
---
---      (4) @null $ takeWhile (==0) $ reverse [d1,d2,...,dn]@
+--     1. @n >= 1@
+--     2. @x = 0.d1d2...dn * (10^^e)@
+--     3. @0 <= di <= 9@
+--     4. @null $ takeWhile (==0) $ reverse [d1,d2,...,dn]@
 --
 -- The last property means that the coefficient will be normalized, i.e. doesn't
 -- contain trailing zeros.
diff --git a/test/test.hs b/test/test.hs
--- a/test/test.hs
+++ b/test/test.hs
@@ -11,9 +11,11 @@
 
 import           Control.Applicative
 import           Control.Monad
+import           Data.Int
 import           Data.Scientific                    as Scientific
 import           Test.Tasty
 import           Test.Tasty.Runners.AntXML
+import           Test.Tasty.HUnit
 import qualified Test.SmallCheck                    as SC
 import qualified Test.SmallCheck.Series             as SC
 import qualified Test.Tasty.SmallCheck              as SC  (testProperty)
@@ -142,20 +144,45 @@
       , testProperty "Integer == Right" $ \(i::Integer) ->
           (floatingOrInteger (fromInteger i) :: Either Double Integer) == Right i
       , smallQuick "Double == Left"
-          (\(d::Double) -> isFloating d SC.==>
+          (\(d::Double) -> genericIsFloating d SC.==>
              (floatingOrInteger (realToFrac d) :: Either Double Integer) == Left d)
-          (\(d::Double) -> isFloating d QC.==>
+          (\(d::Double) -> genericIsFloating d QC.==>
              (floatingOrInteger (realToFrac d) :: Either Double Integer) == Left d)
       ]
+    , testGroup "toBoundedInteger"
+      [ testProperty "correct conversion" $ \s ->
+            case toBoundedInteger s :: Maybe Int64 of
+              Just i -> i == (fromIntegral $ (coefficient s') * 10^(base10Exponent s'))
+                where
+                  s' = normalize s
+              Nothing -> isFloating s ||
+                         s < fromIntegral (minBound :: Int64) ||
+                         s > fromIntegral (maxBound :: Int64)
+      ]
     ]
+  , testGroup "toBoundedInteger"
+    [ testGroup "to Int64" $
+      [ testCase "succ of maxBound" $
+        let i = succ . fromIntegral $ (maxBound :: Int64)
+            s = scientific i 0
+        in (toBoundedInteger s :: Maybe Int64) @?= Nothing
+      , testCase "pred of minBound" $
+        let i = pred . fromIntegral $ (minBound :: Int64)
+            s = scientific i 0
+        in (toBoundedInteger s :: Maybe Int64) @?= Nothing
+      ]
+    ]
+  , testGroup "Predicates"
+    [ testProperty "isFloating" $ \s -> isFloating s ==      genericIsFloating s
+    , testProperty "isInteger"  $ \s -> isInteger  s == not (genericIsFloating s)
+    ]
   ]
 
 testMain :: TestTree -> IO ()
 testMain = defaultMainWithIngredients (antXMLRunner:defaultIngredients)
 
-isFloating :: Double -> Bool
-isFloating 0 = False
-isFloating d = fromInteger (floor d :: Integer) /= d
+genericIsFloating :: RealFrac a => a -> Bool
+genericIsFloating a = fromInteger (floor a :: Integer) /= a
 
 conversionsProperties :: forall realFloat.
                          ( RealFloat    realFloat
