diff --git a/Decimal.cabal b/Decimal.cabal
--- a/Decimal.cabal
+++ b/Decimal.cabal
@@ -1,5 +1,5 @@
 Name:                Decimal
-Version:             0.3.1
+Version:             0.4.1
 License:             BSD3
 License-file:        LICENSE.txt
 Copyright:           Paul Johnson, 2013
diff --git a/README.txt b/README.txt
--- a/README.txt
+++ b/README.txt
@@ -27,8 +27,6 @@
    cabal build
    cabal test
 
-Data.Decimal is an instance of Arbitrary, for your convenience in
-writing your own tests.
 
 
 Version 0.2.1
@@ -57,3 +55,15 @@
 These changes alter the API. Hence the increment to the major version number.
 
 Thanks to Alexey Uimanov (s9gf4ult at gmail.com).
+
+Version 0.4.1
+-------------
+
+Improved "Read" instance. Now handles "1.2e3" and "reads" only returns a 
+   single parse.
+Corrected documentation.
+Added "Enum" instance.
+"decimalConvert" now returns a Maybe value. The old version has been renamed
+   to "unsafeDecimalConvert.
+
+   
diff --git a/src/Data/Decimal.hs b/src/Data/Decimal.hs
--- a/src/Data/Decimal.hs
+++ b/src/Data/Decimal.hs
@@ -4,35 +4,44 @@
 -- @m@ and @e@ are integers.  The exponent @e@ is an unsigned Word8.  Hence
 -- the smallest value that can be represented is @10^-255@.
 -- 
--- Unary arithmetic results have the exponent of the argument.  Binary
--- arithmetic results have an exponent equal to the maximum of the exponents
--- of the arguments.
+-- Unary arithmetic results have the exponent of the argument.  
+-- Addition and subtraction results have an exponent equal to the 
+-- maximum of the exponents of the arguments. Other operators have
+-- exponents sufficient to show the exact result, up to a limit of
+-- 255:
 -- 
--- Decimal numbers are defined as instances of @Real@.  This means that
--- conventional division is not defined.  Instead the functions @divide@ and 
--- @allocate@ will split a decimal amount into lists of results.  These 
--- results are guaranteed to sum to the original number.  This is a useful
--- property when doing financial arithmetic.
+-- > 0.15 * 0.15 :: Decimal    = 0.0225
+-- > (1/3) :: Decimal          = 0.33333333333333...
+-- > decimalPlaces (1/3)       = 255
 -- 
+-- While @(/)@ is defined, you don't normally want to use it. Instead
+-- The functions "divide" and "allocate" will split a decimal amount 
+-- into lists of results which are guaranteed to sum to the original 
+-- number.  This is a useful property when doing financial arithmetic.
+-- 
 -- The arithmetic on mantissas is always done using @Integer@, regardless of
--- the type of @DecimalRaw@ being manipulated.  In practice it is recommended
--- that @Decimal@ be used, with other types being used only where necessary
--- (e.g. to conform to a network protocol).
+-- the type of @DecimalRaw@ being manipulated.  In practice it is strongly
+-- recommended that @Decimal@ be used, with other types being used only where 
+-- necessary (e.g. to conform to a network protocol). For instance 
+-- @(1/3) :: DecimalRaw Int@ does not give the right answer.
 
+
 module Data.Decimal (
    -- ** Decimal Values
    DecimalRaw (..),
    Decimal,
    realFracToDecimal,
    decimalConvert,
+   unsafeDecimalConvert,
    roundTo,
    (*.),
    divide,
    allocate,
    eitherFromRational,
-   normalizeDecimal,
+   normalizeDecimal
 ) where
 
+
 import Control.Monad.Instances ()
 import Control.DeepSeq
 import Data.Char
@@ -51,8 +60,6 @@
 -- will return \"1.500\".  Conversely the "Read" instance will use the decimal
 -- places to determine the precision.
 -- 
--- Arithmetic and comparision operators convert their arguments to the 
--- greater of the two precisions, and return a result of that precision.  
 -- Regardless of the type of the arguments, all mantissa arithmetic is done
 -- using @Integer@ types, so application developers do not need to worry about
 -- overflow in the internal algorithms.  However the result of each operator
@@ -63,7 +70,7 @@
                                   deriving (Typeable)
 
 
--- | Arbitrary precision decimal type.  As a rule programs should do decimal
+-- | Arbitrary precision decimal type.  Programs should do decimal
 -- arithmetic with this type and only convert to other instances of 
 -- "DecimalRaw" where required by an external interface.
 -- 
@@ -73,6 +80,17 @@
 
 instance (Integral i, NFData i) => NFData (DecimalRaw i) where
     rnf (Decimal _ i) = rnf i
+    
+instance (Integral i) => Enum (DecimalRaw i) where
+   succ x = x + 1
+   pred x = x - 1
+   toEnum = fromIntegral
+   fromEnum = fromIntegral . decimalMantissa . roundTo 0
+   enumFrom = iterate (+1)
+   enumFromThen x1 x2 = let dx = x2 - x1 in iterate (+dx) x1
+   enumFromTo x1 x2 = takeWhile (<= x2) $ iterate (+1) x1
+   enumFromThenTo x1 x2 x3 = takeWhile (<= x3) $ enumFromThen x1 x2
+   
 
 -- | Convert a real fractional value into a Decimal of the appropriate 
 -- precision.
@@ -80,20 +98,36 @@
 realFracToDecimal e r = Decimal e $ round (r * (10^e))
 
 
--- Internal function to divide and return the nearest integer.
+-- Internal function to divide and return the nearest integer. Rounds 0.5 away from zero.
 divRound :: (Integral a) => a -> a -> a
-divRound n1 n2 = if abs r > abs (n2 `quot` 2) then n + signum n else n
+divRound n1 n2 = if abs r * 2 >= abs n2 then n + signum n1 else n
     where (n, r) = n1 `quotRem` n2
 
 
 -- | Convert a @DecimalRaw@ from one base representation to another.  Does
--- not check for overflow in the new representation.
-decimalConvert :: (Integral a, Integral b) => DecimalRaw a -> DecimalRaw b
-decimalConvert (Decimal e n) = Decimal e $ fromIntegral n
+-- not check for overflow in the new representation. Only use after
+-- using "roundTo" to put an upper value on the exponent, or to convert
+-- to a larger representation.
+unsafeDecimalConvert :: (Integral a, Integral b) => DecimalRaw a -> DecimalRaw b
+unsafeDecimalConvert (Decimal e n) = Decimal e $ fromIntegral n
 
 
--- | Round a @DecimalRaw@ to a specified number of decimal places.
-roundTo :: (Integral i) => Word8 -> DecimalRaw i -> DecimalRaw Integer
+-- | Convert a @DecimalRaw@ from one base to another. Returns @Nothing@ if
+-- this would cause arithmetic overflow.
+decimalConvert :: (Integral a, Integral b, Bounded b) =>
+   DecimalRaw a -> Maybe (DecimalRaw b)
+decimalConvert (Decimal e n) = 
+   let n1 :: Integer
+       n1 = fromIntegral n
+       n2 = fromIntegral n   -- Of type b.
+       ub = fromIntegral $ max maxBound n2  -- Can't say "maxBound :: b", so do this instead.
+       lb = fromIntegral $ min minBound n2
+   in if lb <= n1 && n1 <= ub then Just $ Decimal e n2 else Nothing
+
+
+-- | Round a @DecimalRaw@ to a specified number of decimal places. 
+-- If the value ends in @5@ then it is rounded away from zero. 
+roundTo :: (Integral i) => Word8 -> DecimalRaw i -> DecimalRaw i
 roundTo d (Decimal e n) = Decimal d $ fromIntegral n1
     where
       n1 = case compare d e of
@@ -105,8 +139,7 @@
 
 
 -- Round the two DecimalRaw values to the largest exponent.
-roundMax :: (Integral i) => 
-            DecimalRaw i -> DecimalRaw i -> (Word8, Integer, Integer)
+roundMax :: (Integral i) => DecimalRaw i -> DecimalRaw i -> (Word8, i, i)
 roundMax d1@(Decimal e1 _) d2@(Decimal e2 _) = (e, n1, n2)
     where
       e = max e1 e2
@@ -116,7 +149,7 @@
 
 instance (Integral i, Show i) => Show (DecimalRaw i) where
    showsPrec _ (Decimal e n)
-       | e == 0     = (concat [signStr, strN] ++)
+       | e == 0     = ((signStr ++ strN) ++)
        | otherwise  = (concat [signStr, intPart, ".", fracPart] ++)
        where
          strN = show $ abs n
@@ -126,16 +159,34 @@
          (intPart, fracPart) = splitAt (max 1 (len - fromIntegral e)) padded
 
 instance (Integral i, Read i) => Read (DecimalRaw i) where
-    readsPrec _ = 
-        readP_to_S $ do
-          (intPart, _) <- gather $ do
-                            optional $ char '-'
-                            munch1 isDigit
-          fractPart    <- option "" $ do
+    readsPrec _ = readP_to_S readDecimalP
+        
+
+-- | Parse a Decimal value. Used for the Read instance.
+readDecimalP :: (Integral i, Read i) => ReadP (DecimalRaw i)
+readDecimalP = do
+          s1           <- myOpt '+' $ char '-' +++ char '+'
+          intPart      <- munch1 isDigit
+          fractPart    <- myOpt "" $ do
                             _ <- char '.'
                             munch1 isDigit
-          return $ Decimal (fromIntegral $ length fractPart) $ read $ 
-                 intPart ++ fractPart
+          expPart <- myOpt 0 $ do
+                            _  <- char 'e' +++ char 'E'
+                            s2 <- myOpt '+' $ char '-' +++ char '+'
+                            fmap (applySign s2 . strToInt) $ munch1 isDigit
+          let n = applySign s1 $ strToInt $ intPart ++ fractPart
+              e = length fractPart - expPart
+          if e < 0
+             then return $ Decimal 0 $ n * 10 ^ negate e
+             else if e < 256
+                then return $ Decimal (fromIntegral e) n
+                else pfail
+    where
+       strToInt :: (Integral n) => String -> n
+       strToInt = foldl (\t v -> 10 * t + v) 0 . map (fromIntegral . subtract (ord '0') . ord)
+       applySign '-' v = negate v
+       applySign _   v = v
+       myOpt d p = p <++ return d
 
 
 instance (Integral i) => Eq (DecimalRaw i) where
@@ -151,7 +202,7 @@
         where (e, n1, n2) = roundMax d1 d2
     d1 - d2 = Decimal e $ fromIntegral (n1 - n2)
         where (e, n1, n2) = roundMax d1 d2
-    d1 * d2 = normalizeDecimal $ realFracToDecimal maxBound $ (toRational d1) * (toRational d2)
+    d1 * d2 = normalizeDecimal $ realFracToDecimal maxBound $ toRational d1 * toRational d2
 
     abs (Decimal e n) = Decimal e $ abs n
     signum (Decimal _ n) = fromIntegral $ signum n
@@ -161,8 +212,12 @@
     toRational (Decimal e n) = fromIntegral n % (10 ^ e)
 
 instance (Integral i) => Fractional (DecimalRaw i) where
-  fromRational r = normalizeDecimal $ realFracToDecimal maxBound r
-  a / b = fromRational $ (toRational a) / (toRational b)
+  fromRational r = 
+     let
+        v :: Decimal
+        v = normalizeDecimal $ realFracToDecimal maxBound r
+     in unsafeDecimalConvert v 
+  a / b = fromRational $ toRational a / toRational b
 
 instance (Integral i) => RealFrac (DecimalRaw i) where
   properFraction a = (rnd, fromRational rep)
@@ -178,12 +233,12 @@
 -- The portions are represented as a list of pairs.  The first part of each
 -- pair is the number of portions, and the second part is the portion value.
 -- Hence 10 dollars divided 3 ways will produce @[(2, 3.33), (1, 3.34)]@.
-divide :: (Integral i) => DecimalRaw i -> Int -> [(Int, DecimalRaw i)]
+divide :: Decimal -> Int -> [(Int, Decimal)]
 divide (Decimal e n) d 
     | d > 0 = 
         case n `divMod` fromIntegral d of
-          (result, 0) -> [(fromIntegral d, Decimal e result)]
-          (result, r) -> [(fromIntegral d - fromIntegral r,
+          (result, 0) -> [(d, Decimal e result)]
+          (result, r) -> [(d - fromIntegral r,
                            Decimal e result), 
                           (fromIntegral r, Decimal e (result+1))]
     | otherwise = error "Data.Decimal.divide: Divisor must be > 0."
@@ -199,18 +254,17 @@
 -- 
 -- > let result = allocate d parts
 -- > in all (== d / sum parts) $ zipWith (/) result parts
-allocate :: (Integral i) => DecimalRaw i -> [Integer] -> [DecimalRaw i]
+allocate :: Decimal -> [Integer] -> [Decimal]
 allocate (Decimal e n) ps
     | total == 0  = 
         error "Data.Decimal.allocate: allocation list must not sum to zero."
     | otherwise   = map (Decimal e) $ zipWith (-) ts (tail ts)
     where
       ts = map fst $ scanl nxt (n, total) ps
-      nxt (n1, t1) p1 = (n1 - (n1 * fromIntegral p1) `zdiv` t1, 
-                         t1 - fromIntegral p1)
+      nxt (n1, t1) p1 = (n1 - (n1 * p1) `zdiv` t1, t1 - p1)
       zdiv 0 0 = 0
       zdiv x y = x `divRound` y
-      total = fromIntegral $ sum ps
+      total = sum ps
 
 
 -- | Multiply a @DecimalRaw@ by a @RealFrac@ value.
@@ -246,12 +300,12 @@
     (f5, done) = factorN 5 rest
     e = max f2 f5
     m = num * ((10^e) `div` den)
-    we = if e > (fromIntegral (maxBound :: Word8)) --  FIXME: will fail if DecimalRaw changed
+    we = if e > fromIntegral (maxBound :: Word8)
          then Left $ show e ++ " is too big ten power to represent as Decimal"
          else Right $ fromIntegral e
 
--- | Reduce the exponent of the decimal numer to the minimal posible value
-normalizeDecimal :: (Integral i) => (DecimalRaw i) -> (DecimalRaw i)
+-- | Reduce the exponent of the decimal number to the minimal possible value
+normalizeDecimal :: (Integral i) => DecimalRaw i -> DecimalRaw i
 normalizeDecimal r = case eitherFromRational $ toRational r of
   Right x -> x
-  Left e -> error $ "Imposible happened: " ++ e
+  Left e -> error $ "Impossible happened: " ++ e
diff --git a/tests/Main.hs b/tests/Main.hs
--- a/tests/Main.hs
+++ b/tests/Main.hs
@@ -7,7 +7,6 @@
 import Control.Applicative
 
 import Test.QuickCheck
-import qualified Test.QuickCheck.Property as P
 import Test.Framework as TF (defaultMain, testGroup, Test)
 import Test.Framework.Providers.HUnit
 import Test.Framework.Providers.QuickCheck2 (testProperty)
@@ -21,14 +20,14 @@
   --   return $ Decimal (fromIntegral $ abs e) m
       
 instance (Integral i, Arbitrary i) => CoArbitrary (DecimalRaw i) where
-    coarbitrary (Decimal e m) gen = variant (v:: Integer) gen
+    coarbitrary (Decimal e m) = variant (v:: Integer)
        where v = fromIntegral e + fromIntegral m
   
 -- | "read" is the inverse of "show".
 -- 
 -- > read (show n) == n
 prop_readShow :: Decimal -> Bool
-prop_readShow d =  (read (show d)) == d
+prop_readShow d =  read (show d) == d
 
 -- | Read and show preserve decimal places.
 -- 
@@ -143,7 +142,7 @@
 prop_mulValid a b = ((ad + bd) < fromIntegral (maxBound :: Word8)) ==>
                     (toRational (a * b) == (toRational a) * (toRational b))
   where
-    ad :: Integer
+    ad, bd :: Integer
     ad = fromIntegral $ decimalPlaces a
     bd = fromIntegral $ decimalPlaces b
 
@@ -219,7 +218,13 @@
                 testCase "1.0 * pi"      (dec 1 31    @=? dec 1 10 *. piD),
                 testCase "1.23 * pi"     (dec 2 386   @=? dec 2 123 *. piD),
                 testCase "Decimal to DecimalRaw Int" 
-                                         (decimalConvert (dec 2 123) @=? dec1 2 123),
-                testCase "1.234 to rational" (1234 % 1000 @=? (toRational (dec 3 1234)))
+                                         (decimalConvert (dec 2 123) @=? Just (dec1 2 123)),
+                testCase "decimalConvert overflow prevention"
+                                         (decimalConvert (1/3) @=? (Nothing :: Maybe (DecimalRaw Int))),
+                testCase "1.234 to rational" (1234 % 1000 @=? toRational (dec 3 1234)),
+                testCase "fromRational (1%10) for DecimalRaw Int"  -- Fixed bug #3
+                                         (let v :: DecimalRaw Int
+                                              v = fromRational (1%10)
+                                          in toRational v @=? 1%10)
                 ]
        ]
