diff --git a/CHANGES.md b/CHANGES.md
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -1,7 +1,13 @@
 * Hackage: <http://hackage.haskell.org/package/crackNum>
 * GitHub:  <http://github.com/LeventErkok/crackNum/>
 
-* Latest Hackage released version: 2.2, 2018-09-01
+* Latest Hackage released version: 2.3, 2018-11-17
+
+### Version 2.3, 2018-11-17
+
+  * Remove dependency on the ieee754 and reinterpret-cast packages. The goal is
+    to remove any FFI dependencies. We now define and export the required
+    utilities directly in the CrackNum package.
 
 ### Version 2.2, 2018-09-01
 
diff --git a/Data/Numbers/CrackNum.hs b/Data/Numbers/CrackNum.hs
--- a/Data/Numbers/CrackNum.hs
+++ b/Data/Numbers/CrackNum.hs
@@ -9,7 +9,9 @@
 -- A library for formatting/analyzing FP and Integer values
 -----------------------------------------------------------------------------
 
+{-# LANGUAGE    FlexibleContexts #-}
 {-# LANGUAGE    NamedFieldPuns    #-}
+
 {-# OPTIONS_GHC -fno-warn-orphans #-}
 
 module Data.Numbers.CrackNum
@@ -19,6 +21,8 @@
       , floatToFP, doubleToFP, stringToFP, integerToFP
         -- * Displaying FP and Int/Word values
       , displayFP, displayWord
+        -- * Converting between floats and bit-representations
+      , floatToWord, wordToFloat, doubleToWord, wordToDouble
    )
    where
 
@@ -29,13 +33,16 @@
 import Data.Maybe (isJust, fromJust, fromMaybe, catMaybes)
 
 import Numeric
-import Numeric.IEEE
 import Data.Numbers.CrackNum.Data
 import Data.Numbers.CrackNum.Utils
-import Data.ReinterpretCast
 
 import qualified Data.Numbers.FloatingHex as FH
 
+import Data.Word         (Word32, Word64)
+import Data.Array.ST     (newArray, readArray, MArray, STUArray)
+import Data.Array.Unsafe (castSTUArray)
+import GHC.ST            (runST, ST)
+
 -- | Crack a Haskell Integer value as the given precision floating value. The Integer should
 -- be the value corresponding to the bit-pattern as the float is laid out in memory according
 -- to the IEEE rules.
@@ -184,20 +191,33 @@
   where i = map toLower (dropWhile (== '+') input)
         specials :: [(String, (FP, FP))]
         specials = [ (s, (floatToFP f, doubleToFP d))
-                   | (s, (f, d)) <- [ ("infinity",  ( infinity,             infinity))
-                                    , ("-infinity", (-infinity,          -  infinity))
+                   | (s, (f, d)) <- [ ("infinity",  ( infinityF,            infinityD))
+                                    , ("-infinity", (-infinityF,         -  infinityD))
                                     , ("0",         ( 0,                    0))
                                     , ("-0",        (-0,                 -  0))
-                                    , ("max",       ( maxFinite,            maxFinite))
-                                    , ("-max",      (-maxFinite,         -  maxFinite))
-                                    , ("min",       ( minNormal,            minNormal))
-                                    , ("-min",      (-minNormal,         -  minNormal))
-                                    , ("epsilon",   ( epsilon,              epsilon))]  ]
+                                    , ("max",       ( maxFiniteF,           maxFiniteD))
+                                    , ("-max",      (-maxFiniteF,         - maxFiniteD))
+                                    , ("min",       ( minNormalF,           minNormalD))
+                                    , ("-min",      (-minNormalF,         - minNormalD))
+                                    , ("epsilon",   ( epsilonF,             epsilonD))]  ]
                                  ++ [ ("ulp",       (integerToFP SP 1,          integerToFP DP 1))
                                     , ("nan",       (integerToFP SP 0x7f800001, integerToFP DP 0x7ff0000000000001))
                                     , ("snan",      (integerToFP SP 0x7f800001, integerToFP DP 0x7ff0000000000001))
                                     , ("qnan",      (integerToFP SP 0x7fc00000, integerToFP DP 0x7ff8000000000000))
                                     ]
+
+        infinityF, maxFiniteF, minNormalF, epsilonF :: Float
+        infinityF  = 1/0
+        maxFiniteF = 3.40282347e+38
+        minNormalF = 1.17549435e-38
+        epsilonF   = 1.19209290e-07
+
+        infinityD, maxFiniteD, minNormalD, epsilonD :: Double
+        infinityD  = 1/0
+        maxFiniteD = 1.7976931348623157e+308
+        minNormalD = 2.2250738585072014e-308
+        epsilonD   = 2.2204460492503131e-16
+
         mbF, mbD :: Maybe FP
         (mbF, mbD) = case (i `lookup` specials, rd i :: Maybe Float, rd i :: Maybe Double) of
                        (Just (f, d), _     , _     ) -> (Just f,             Just d)
@@ -218,3 +238,36 @@
 -- | Turn a Haskell double to the internal detailed FP representation
 doubleToFP :: Double -> FP
 doubleToFP = integerToFP DP . toInteger . doubleToWord
+
+-------------------------------------------------------------------------
+-- Reinterpreting float/double as word32/64 and back. Here, we use the
+-- definitions from the reinterpret-cast package:
+--
+--     http://hackage.haskell.org/package/reinterpret-cast
+--
+-- The reason we steal these definitions is to make sure we keep minimal
+-- dependencies and no FFI requirements anywhere.
+-------------------------------------------------------------------------
+-- | Reinterpret-casts a `Float` to a `Word32`.
+floatToWord :: Float -> Word32
+floatToWord x = runST (cast x)
+{-# INLINEABLE floatToWord #-}
+
+-- | Reinterpret-casts a `Word32` to a `Float`.
+wordToFloat :: Word32 -> Float
+wordToFloat x = runST (cast x)
+{-# INLINEABLE wordToFloat #-}
+
+-- | Reinterpret-casts a `Double` to a `Word64`.
+doubleToWord :: Double -> Word64
+doubleToWord x = runST (cast x)
+{-# INLINEABLE doubleToWord #-}
+
+-- | Reinterpret-casts a `Word64` to a `Double`.
+wordToDouble :: Word64 -> Double
+wordToDouble x = runST (cast x)
+{-# INLINEABLE wordToDouble #-}
+
+{-# INLINE cast #-}
+cast :: (MArray (STUArray s) a (ST s), MArray (STUArray s) b (ST s)) => a -> ST s b
+cast x = newArray (0 :: Int, 0) x >>= castSTUArray >>= flip readArray 0
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -7,7 +7,7 @@
 
 ### Command line options:
 
-    crackNum v2.2, (c) Levent Erkok. Released with a BSD3 license.
+    crackNum v2.3, (c) Levent Erkok. Released with a BSD3 license.
     Usage: crackNum precision bit/hex-pattern
               --hp        16 bit half     precision
               --sp        32 bit single   precision
diff --git a/crackNum.cabal b/crackNum.cabal
--- a/crackNum.cabal
+++ b/crackNum.cabal
@@ -1,5 +1,5 @@
 Name:                crackNum
-Version:             2.2
+Version:             2.3
 Synopsis:            Crack various integer, floating-point data formats
 Description:         Crack HP, SP and DP floats and 8, 16, 32, 64 bit words and integers.
                      .
@@ -23,7 +23,7 @@
    main-is      : Data/Numbers/CrackNum/Main.hs
    ghc-options  : -Wall
    default-language: Haskell2010
-   build-depends: base >= 4 && < 5, ieee754, reinterpret-cast, FloatingHex >= 0.4
+   build-depends: base >= 4 && < 5, array >= 0.4.0.1, FloatingHex >= 0.4
    other-modules: Data.Numbers.CrackNum
                 , Data.Numbers.CrackNum.Utils
                 , Data.Numbers.CrackNum.Data
@@ -32,7 +32,7 @@
 Library
   ghc-options     : -Wall
   default-language: Haskell2010
-  Build-Depends   : base >= 4 && < 5, ieee754, reinterpret-cast, FloatingHex >= 0.4
+  Build-Depends   : base >= 4 && < 5, array >= 0.4.0.1, FloatingHex >= 0.4
   Exposed-modules : Data.Numbers.CrackNum
   other-modules   : Data.Numbers.CrackNum.Utils
                   , Data.Numbers.CrackNum.Data
