diff --git a/CHANGES.md b/CHANGES.md
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -1,4 +1,18 @@
 
+0.5.0
+=====
+
+Note that changes in `fromInteger` and `toInteger` implementations break backwards compatibility.
+I hope this will not cause major problems, let me know otherwise.
+
+* Make _bv_ with compatible with GHC 8.4.1 (_base_ 4.11). Thanks to Kosyrev Serge!
+* Define `toInteger` as `int` rather than `nat`.
+* Make `fromInteger` consistent and always encode in two's complement, also positive integers.
+* As a result of the two previous changes, now `toInteger . fromInteger == id`, as it should be.
+* Add `Read BV` instance (based on `Text.Read`, so GHC-only).
+* Fix a few bugs in the non-GMP implementation. (Fortunately, GMP is the default.)
+* Remove upper bounds on testing dependencies.
+
 0.4.1
 =====
 
diff --git a/bv.cabal b/bv.cabal
--- a/bv.cabal
+++ b/bv.cabal
@@ -1,6 +1,6 @@
 
 Name:                bv
-Version:             0.4.1
+Version:             0.5
 Synopsis:            Bit-vector arithmetic library
 Description:         Bit-vectors implemented as a thin wrapper over integers.
 Homepage:            https://github.com/iagoabal/haskell-bv
@@ -52,15 +52,16 @@
   Other-Extensions:    BangPatterns, DeriveDataTypeable, MagicHash
   Build-depends:       base >=4.6 && <5
   if impl(ghc) && flag(gmp)
-    Build-depends: integer-gmp, ghc-prim
+    Build-depends:     integer-gmp >=0.5.1,
+                       ghc-prim
 
 Executable bv-tester
   if flag(test)
     Buildable:           True
     Build-depends:       base >=4.6 && <5,
-                         QuickCheck >=2.4 && < 2.7,
-                         test-framework-quickcheck2 ==0.3.*,
-                         test-framework-th ==0.2.*
+                         QuickCheck >=2.4,
+                         test-framework-quickcheck2 >=0.3,
+                         test-framework-th >=0.2
   else
     Buildable:           False
 
diff --git a/src/Data/BitVector.hs b/src/Data/BitVector.hs
--- a/src/Data/BitVector.hs
+++ b/src/Data/BitVector.hs
@@ -3,7 +3,9 @@
 {-# LANGUAGE BangPatterns #-}
 {-# LANGUAGE DeriveDataTypeable #-}
 
-#if MIN_VERSION_integer_gmp(0,5,1)
+-- NOTE: defined(MIN_VERSION_integer_gmp) == package configured with -fgmp
+
+#if defined(MIN_VERSION_integer_gmp)
 {-# LANGUAGE MagicHash #-}
 #endif
 
@@ -23,7 +25,7 @@
 -- * Bit-vectors are interpreted as unsigned integers
 --   (i.e. natural numbers) except for some specific /signed/ operations.
 --
--- * Most operations are in some way /size-polymorphic/ and, if required, 
+-- * Most operations are in some way /size-polymorphic/ and, if required,
 --   will perform padding to adjust the size of input bit-vectors.
 --
 -- For documentation purposes we will write @[n]k@ to denote a bit-vector
@@ -86,6 +88,7 @@
   , showHex
   ) where
 
+import           Control.Monad ( Monad(..), when )
 import           Control.Exception ( assert )
 
 import           Data.Bits
@@ -95,12 +98,17 @@
 import qualified Data.List as List
 import           Data.Monoid ( Monoid(..) )
 import           Data.Ord
+#ifdef __GLASGOW_HASKELL__
+import qualified Text.Read as R
+#endif
 import           Data.Typeable ( Typeable )
 
-#if MIN_VERSION_integer_gmp(0,5,1)
+#if defined(MIN_VERSION_integer_gmp)
 import qualified GHC.Integer.Logarithms as I
 import           GHC.Prim ( (+#) )
 import           GHC.Types ( Int(..) )
+#else
+import           Data.Int ( Int )
 #endif
 
 import           Prelude
@@ -110,6 +118,9 @@
   , Integral(..), Integer
   , Maybe(..)
   , Real(..)
+#if MIN_VERSION_base(4,11,0)
+  , Semigroup(..)
+#endif
   , Show(..), String
   , const
   , error
@@ -162,6 +173,18 @@
 instance Show BV where
   show (BV n a) = "[" ++ show n ++ "]" ++ show a
 
+#ifdef __GLASGOW_HASKELL__
+instance R.Read BV where
+  readPrec = do
+    R.Punc "[" <- R.lexP
+    n <- R.step R.readPrec
+    when (n < 0) R.pfail
+    R.Punc "]" <- R.lexP
+    a <- R.step R.readPrec
+    when (a < 0) R.pfail
+    return (bitVec (n::Int) (a::Integer))
+#endif
+
 ----------------------------------------------------------------------
 --- Safety checking & Errors
 
@@ -469,12 +492,8 @@
   {-# INLINE abs #-}
   signum u = bitVec 2 $ signum $ int u
   {-# INLINE signum #-}
-#if MIN_VERSION_integer_gmp(0,5,1)
-  fromInteger i = bitVec n i
-    where n = I# (I.integerLog2# i +# 1#)
-#else
-  fromInteger i = bitVec (integerWidth i) i
-#endif
+  fromInteger !i = bitVec n i
+    where !n = if i >= 0 then integerWidth i + 1 else integerWidth i
   {-# INLINE fromInteger #-}
 
 -- | Bit-vector 'signum' as an 'Integral'.
@@ -496,7 +515,7 @@
   {-# INLINE quotRem #-}
   divMod = quotRem
   {-# INLINE divMod #-}
-  toInteger = nat
+  toInteger = int
   {-# INLINE toInteger #-}
 
 -- | Bit-vector exponentiation.
@@ -537,11 +556,14 @@
 lg2 :: BV -> BV
 lg2 (BV _ 0) = error "Data.BitVector.lg2: zero bit-vector"
 lg2 (BV n 1) = BV n 0
-#if MIN_VERSION_integer_gmp(0,5,1)
+#if defined(MIN_VERSION_integer_gmp)
 lg2 (BV n a) = BV n (toInteger a')
   where a' = I# (I.integerLog2# a)
 #else
-lg2 (BV n a) = BV n $ toInteger $ integerWidth (a-1)
+lg2 (BV n a) = BV n $ go 0 1
+  where go !k !b | b == a    = k
+                 | b > a     = k-1
+                 | otherwise = go (k+1) (2*b)
 #endif
 {-# INLINE lg2 #-}
 
@@ -566,14 +588,22 @@
 concat = join
 
 -- This is the most sensible monoid instance until we have size types!
+
 instance Monoid BV where
   mempty  = nil
   {-# INLINE mempty #-}
-  mappend = (#)
-  {-# INLINE mappend #-}
   mconcat = join
   {-# INLINE mconcat #-}
+#if !MIN_VERSION_base(4,11,0)
+  mappend = (#)
+  {-# INLINE mappend #-}
+#else
 
+instance Semigroup BV where
+  (<>) = (#)
+  {-# INLINE (<>) #-}
+#endif
+
 -- | Logical extension.
 --
 -- >>> zeroExtend 3 [1]1
@@ -912,19 +942,23 @@
 maxNat n = 2^n - 1
 {-# INLINE maxNat #-}
 
-#ifndef MIN_VERSION_integer_gmp
 -- | Minimum width of a bit-vector to represent a given integer number.
 --
--- >>> integerWith 4
+-- >>> integerWidth 4
 -- 3
 --
--- >>> integerWith (-4)
+-- >>> integerWidth (-4)
 -- 4
 integerWidth :: Integer -> Int
+#if defined(MIN_VERSION_integer_gmp)
 integerWidth !n
+  | n >= 0    = I# (I.integerLog2# n +# 1#)
+  | otherwise = I# (I.integerLog2# (-n) +# 2#)
+#else
+integerWidth !n
   | n >= 0    = go 1 1
   | otherwise = 1 + integerWidth (abs n)
   where go !k !k_max | k_max >= n = k
                      | otherwise  = go (k+1) (2*k_max+1)
-{-# INLINE integerWidth #-}
 #endif
+{-# INLINE integerWidth #-}
diff --git a/test/Properties.hs b/test/Properties.hs
--- a/test/Properties.hs
+++ b/test/Properties.hs
@@ -93,11 +93,13 @@
   let a = nat u in
   a >= 0 && a < 2^n
 
+-- * fromInteger
+
 prop_bv_nat :: Integer -> Property
 prop_bv_nat i = i >= 0 ==> nat(fromInteger i) == i
 
-prop_bv_neg :: Integer -> Property
-prop_bv_neg i = i < 0 ==> int(fromInteger i) == i
+prop_bv_id :: Integer -> Bool
+prop_bv_id i = toInteger (fromInteger i :: BV) == i
 
 -- * Indexing
 
@@ -180,6 +182,14 @@
 prop_exp_spec a = forAll anExp $ \e ->
   e /= 0 ==> pow a e ==. a^e
 
+-- * Logarithm
+
+prop_lg2 :: BV -> Property
+prop_lg2 a = a /= 0 ==>
+  let b = lg2 a in
+     2^(nat b) <= nat a
+  && nat a < 2^(nat b + 1)
+
 -- * Not
 
 prop_not_id :: BV -> Bool
@@ -256,3 +266,8 @@
 prop_group_join_id :: BV -> Property
 prop_group_join_id a = forallDivisorOf (size a) $ \n ->
   BV.join (BV.group n a) ==. a
+
+-- * Show & Read
+
+prop_show_read_id :: BV -> Bool
+prop_show_read_id a = read (show a) ==. a
