diff --git a/binary.cabal b/binary.cabal
index 70161c4067ff6afff8ead3fd6dac813c56821fa8..a08de8d098aa48ac57d39cd43fa25459beff6d22 100644
--- a/binary.cabal
+++ b/binary.cabal
@@ -41,7 +41,8 @@ library
 
   other-modules:   Data.Binary.Class,
                    Data.Binary.Internal,
-                   Data.Binary.Generic
+                   Data.Binary.Generic,
+                   Data.Binary.FloatCast
   if impl(ghc <= 7.6)
     -- prior to ghc-7.4 generics lived in ghc-prim
     build-depends: ghc-prim
@@ -168,6 +169,7 @@ benchmark generics-bench
     unordered-containers,
     zlib,
     criterion
+    
   other-modules:
     GenericsBenchCache
     GenericsBenchTypes
diff --git a/src/Data/Binary/FloatCast.hs b/src/Data/Binary/FloatCast.hs
new file mode 100644
index 0000000000000000000000000000000000000000..2eb86f0aa987143b21c0cd93346ff56ac915479a
--- /dev/null
+++ b/src/Data/Binary/FloatCast.hs
@@ -0,0 +1,45 @@
+
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE Trustworthy #-}
+
+-- | This module was written based on
+--   <http://hackage.haskell.org/package/reinterpret-cast-0.1.0/docs/src/Data-ReinterpretCast-Internal-ImplArray.html>.
+--
+--   Implements casting via a 1-elemnt STUArray, as described in
+--   <http://stackoverflow.com/a/7002812/263061>.
+module Data.Binary.FloatCast
+  ( floatToWord
+  , wordToFloat
+  , doubleToWord
+  , wordToDouble
+  ) where
+
+import Data.Word (Word32, Word64)
+import Data.Array.ST (newArray, readArray, MArray, STUArray)
+import Data.Array.Unsafe (castSTUArray)
+import GHC.ST (runST, ST)
+
+-- | Reinterpret-casts a `Float` to a `Word32`.
+floatToWord :: Float -> Word32
+floatToWord x = runST (cast x)
+{-# INLINE floatToWord #-}
+
+-- | Reinterpret-casts a `Word32` to a `Float`.
+wordToFloat :: Word32 -> Float
+wordToFloat x = runST (cast x)
+{-# INLINE wordToFloat #-}
+
+-- | Reinterpret-casts a `Double` to a `Word64`.
+doubleToWord :: Double -> Word64
+doubleToWord x = runST (cast x)
+{-# INLINE doubleToWord #-}
+
+-- | Reinterpret-casts a `Word64` to a `Double`.
+wordToDouble :: Word64 -> Double
+wordToDouble x = runST (cast x)
+{-# INLINE wordToDouble #-}
+
+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
+{-# INLINE cast #-}
diff --git a/src/Data/Binary/Get.hs b/src/Data/Binary/Get.hs
index 40e3e70ff68c148a5d9d826b4d36c025d6ae3a30..62207594e68367836cf912165f817be2509343b9 100644
--- a/src/Data/Binary/Get.hs
+++ b/src/Data/Binary/Get.hs
@@ -205,6 +205,14 @@ module Data.Binary.Get (
     , getInt32host
     , getInt64host
 
+    -- ** Decoding Floats/Doubles
+    , getFloatbe
+    , getFloatle
+    , getFloathost
+    , getDoublebe
+    , getDoublele
+    , getDoublehost
+
     -- * Deprecated functions
     , runGetState -- DEPRECATED
     , remaining -- DEPRECATED
@@ -229,6 +237,9 @@ import GHC.Base
 import GHC.Word
 #endif
 
+-- needed for casting words to float/double
+import Data.Binary.FloatCast (wordToFloat, wordToDouble)
+
 -- $lazyinterface
 -- The lazy interface consumes a single lazy 'L.ByteString'. It's the easiest
 -- interface to get started with, but it doesn't support interleaving I\/O and
@@ -529,33 +540,33 @@ word64le = \s ->
 {-# INLINE word64le #-}
 
 
--- | Read an Int16 in big endian format
+-- | Read an Int16 in big endian format.
 getInt16be :: Get Int16
 getInt16be = fromIntegral <$> getWord16be
 {-# INLINE getInt16be #-}
 
--- | Read an Int32 in big endian format
+-- | Read an Int32 in big endian format.
 getInt32be :: Get Int32
 getInt32be =  fromIntegral <$> getWord32be
 {-# INLINE getInt32be #-}
 
--- | Read an Int64 in big endian format
+-- | Read an Int64 in big endian format.
 getInt64be :: Get Int64
 getInt64be = fromIntegral <$> getWord64be
 {-# INLINE getInt64be #-}
 
 
--- | Read an Int16 in little endian format
+-- | Read an Int16 in little endian format.
 getInt16le :: Get Int16
 getInt16le = fromIntegral <$> getWord16le
 {-# INLINE getInt16le #-}
 
--- | Read an Int32 in little endian format
+-- | Read an Int32 in little endian format.
 getInt32le :: Get Int32
 getInt32le =  fromIntegral <$> getWord32le
 {-# INLINE getInt32le #-}
 
--- | Read an Int64 in little endian format
+-- | Read an Int64 in little endian format.
 getInt64le :: Get Int64
 getInt64le = fromIntegral <$> getWord64le
 {-# INLINE getInt64le #-}
@@ -608,6 +619,39 @@ getInt64host = getPtr  (sizeOf (undefined :: Int64))
 {-# INLINE getInt64host #-}
 
 
+------------------------------------------------------------------------
+-- Double/Float reads
+
+-- | Read a 'Float' in big endian IEEE-754 format.
+getFloatbe :: Get Float
+getFloatbe = wordToFloat <$> getWord32be
+{-# INLINE getFloatbe #-}
+
+-- | Read a 'Float' in little endian IEEE-754 format.
+getFloatle :: Get Float
+getFloatle = wordToFloat <$> getWord32le
+{-# INLINE getFloatle #-}
+
+-- | Read a 'Float' in IEEE-754 format and host endian.
+getFloathost :: Get Float
+getFloathost = wordToFloat <$> getWord32host
+{-# INLINE getFloathost #-}
+
+-- | Read a 'Double' in big endian IEEE-754 format.
+getDoublebe :: Get Double
+getDoublebe = wordToDouble <$> getWord64be
+{-# INLINE getDoublebe #-}
+
+-- | Read a 'Double' in little endian IEEE-754 format.
+getDoublele :: Get Double
+getDoublele = wordToDouble <$> getWord64le
+{-# INLINE getDoublele #-}
+
+-- | Read a 'Double' in IEEE-754 format and host endian.
+getDoublehost :: Get Double
+getDoublehost = wordToDouble <$> getWord64host
+{-# INLINE getDoublehost #-}
+
 ------------------------------------------------------------------------
 -- Unchecked shifts
 
diff --git a/src/Data/Binary/Put.hs b/src/Data/Binary/Put.hs
index 9af7c110d2fcf52b640c4829cd9d606823dfdba1..32fb618d8ed49b59468162c81ffa16717ac06257 100644
--- a/src/Data/Binary/Put.hs
+++ b/src/Data/Binary/Put.hs
@@ -49,6 +49,8 @@ module Data.Binary.Put (
     , putInt16be
     , putInt32be
     , putInt64be
+    , putFloatbe
+    , putDoublebe
 
     -- * Little-endian primitives
     , putWord16le
@@ -57,6 +59,8 @@ module Data.Binary.Put (
     , putInt16le
     , putInt32le
     , putInt64le
+    , putFloatle
+    , putDoublele
 
     -- * Host-endian, unaligned writes
     , putWordhost           -- :: Word   -> Put
@@ -67,6 +71,8 @@ module Data.Binary.Put (
     , putInt16host          -- :: Int16  -> Put
     , putInt32host          -- :: Int32  -> Put
     , putInt64host          -- :: Int64  -> Put
+    , putFloathost
+    , putDoublehost
 
     -- * Unicode
     , putCharUtf8
@@ -93,6 +99,8 @@ import Data.Semigroup
 import Control.Applicative
 import Prelude -- Silence AMP warning.
 
+-- needed for casting Floats/Doubles to words.
+import Data.Binary.FloatCast (floatToWord, doubleToWord)
 
 ------------------------------------------------------------------------
 
@@ -346,6 +354,38 @@ putInt64host       :: Int64 -> Put
 putInt64host       = tell . B.putInt64host
 {-# INLINE putInt64host #-}
 
+------------------------------------------------------------------------
+-- Floats/Doubles
+
+-- | Write a 'Float' in big endian IEEE-754 format.
+putFloatbe :: Float -> Put
+putFloatbe = putWord32be . floatToWord
+{-# INLINE putFloatbe #-}
+
+-- | Write a 'Float' in little endian IEEE-754 format.
+putFloatle :: Float -> Put
+putFloatle = putWord32le . floatToWord
+{-# INLINE putFloatle #-}
+
+-- | Write a 'Float' in native in IEEE-754 format and host endian.
+putFloathost :: Float -> Put
+putFloathost = putWord32host . floatToWord
+{-# INLINE putFloathost #-}
+
+-- | Write a 'Double' in big endian IEEE-754 format.
+putDoublebe :: Double -> Put
+putDoublebe = putWord64be . doubleToWord
+{-# INLINE putDoublebe #-}
+
+-- | Write a 'Double' in little endian IEEE-754 format.
+putDoublele :: Double -> Put
+putDoublele = putWord64le . doubleToWord
+{-# INLINE putDoublele #-}
+
+-- | Write a 'Double' in native in IEEE-754 format and host endian.
+putDoublehost :: Double -> Put
+putDoublehost = putWord64host . doubleToWord
+{-# INLINE putDoublehost #-}
 
 ------------------------------------------------------------------------
 -- Unicode
diff --git a/tests/QC.hs b/tests/QC.hs
index 3bda2bd0343be9abfa229a0d7f4cdd10b9836e0a..650d32b5437ca337bc7a53577ec8f95fe6596ac5 100644
--- a/tests/QC.hs
+++ b/tests/QC.hs
@@ -131,6 +131,26 @@ prop_Int64host = roundTripWith putInt64host getInt64host
 prop_Inthost :: Int -> Property
 prop_Inthost = roundTripWith putInthost getInthost
 
+-- Floats and Doubles
+
+prop_Floatbe :: Float -> Property
+prop_Floatbe = roundTripWith putFloatbe getFloatbe
+
+prop_Floatle :: Float -> Property
+prop_Floatle = roundTripWith putFloatle getFloatle
+
+prop_Floathost :: Float -> Property
+prop_Floathost = roundTripWith putFloathost getFloathost
+
+prop_Doublebe :: Double -> Property
+prop_Doublebe = roundTripWith putDoublebe getDoublebe
+
+prop_Doublele :: Double -> Property
+prop_Doublele = roundTripWith putDoublele getDoublele
+
+prop_Doublehost :: Double -> Property
+prop_Doublehost = roundTripWith putDoublehost getDoublehost
+
 
 -- done, partial and fail
 
@@ -552,6 +572,13 @@ tests =
             , testProperty "Int64le"    (p prop_Int64le)
             , testProperty "Int64host"  (p prop_Int64host)
             , testProperty "Inthost"    (p prop_Inthost)
+              -- Float/Double
+            , testProperty "Floatbe"    (p prop_Floatbe)
+            , testProperty "Floatle"    (p prop_Floatle)
+            , testProperty "Floathost"  (p prop_Floathost)
+            , testProperty "Doublebe"   (p prop_Doublebe)
+            , testProperty "Doublele"   (p prop_Doublele)
+            , testProperty "Doublehost" (p prop_Doublehost)
             ]
 
         , testGroup "String utils"