diff --git a/Data/Double/Conversion/ByteString.hs b/Data/Double/Conversion/ByteString.hs
--- a/Data/Double/Conversion/ByteString.hs
+++ b/Data/Double/Conversion/ByteString.hs
@@ -3,7 +3,7 @@
 -- Copyright   : (c) 2011 MailRank, Inc.
 --
 -- License     : BSD-style
--- Maintainer  : bos@mailrank.com
+-- Maintainer  : bos@serpentine.com
 -- Stability   : experimental
 -- Portability : GHC
 --
diff --git a/Data/Double/Conversion/FFI.hs b/Data/Double/Conversion/FFI.hs
--- a/Data/Double/Conversion/FFI.hs
+++ b/Data/Double/Conversion/FFI.hs
@@ -1,11 +1,11 @@
-{-# LANGUAGE ForeignFunctionInterface, MagicHash, UnliftedFFITypes #-}
+{-# LANGUAGE CPP, ForeignFunctionInterface, MagicHash, UnliftedFFITypes #-}
 
 -- |
 -- Module      : Data.Double.Conversion.FFI
 -- Copyright   : (c) 2011 MailRank, Inc.
 --
 -- License     : BSD-style
--- Maintainer  : bos@mailrank.com
+-- Maintainer  : bos@serpentine.com
 -- Stability   : experimental
 -- Portability : GHC
 --
@@ -29,7 +29,11 @@
     ) where
 
 import Data.Word (Word8)
+#if __GLASGOW_HASKELL__ >= 703
+import Foreign.C.Types (CDouble(CDouble), CInt(CInt))
+#else
 import Foreign.C.Types (CDouble, CInt)
+#endif
 import Foreign.Ptr (Ptr)
 import GHC.Prim (MutableByteArray#)
 
diff --git a/Data/Double/Conversion/Text.hs b/Data/Double/Conversion/Text.hs
--- a/Data/Double/Conversion/Text.hs
+++ b/Data/Double/Conversion/Text.hs
@@ -5,7 +5,7 @@
 -- Copyright   : (c) 2011 MailRank, Inc.
 --
 -- License     : BSD-style
--- Maintainer  : bos@mailrank.com
+-- Maintainer  : bos@serpentine.com
 -- Stability   : experimental
 -- Portability : GHC
 --
diff --git a/README.markdown b/README.markdown
--- a/README.markdown
+++ b/README.markdown
@@ -11,11 +11,11 @@
 and other improvements.
 
 Please report bugs via the
-[github issue tracker](https://github.com/mailrank/double-conversion/issues).
+[github issue tracker](https://github.com/bos/double-conversion/issues).
 
-Master [git repository](https://github.com/mailrank/double-conversion):
+Master [git repository](https://github.com/bos/double-conversion):
 
-* `git clone git://github.com/mailrank/double-conversion.git`
+* `git clone git://github.com/bos/double-conversion.git`
 
 There's also a [Mercurial mirror](https://bitbucket.org/bos/double-conversion):
 
@@ -27,4 +27,4 @@
 -------
 
 This library is written and maintained by Bryan O'Sullivan,
-<bos@mailrank.com>.
+<bos@serpentine.com>.
diff --git a/double-conversion.cabal b/double-conversion.cabal
--- a/double-conversion.cabal
+++ b/double-conversion.cabal
@@ -1,12 +1,12 @@
 name:           double-conversion
-version:        0.2.0.1
+version:        0.2.0.3
 license:        BSD3
 license-file:   LICENSE
-homepage:       https://github.com/mailrank/double-conversion
-bug-reports:    https://github.com/mailrank/double-conversion/issues
+homepage:       https://github.com/bos/double-conversion
+bug-reports:    https://github.com/bos/double-conversion/issues
 category:       Text
-author:         Bryan O'Sullivan <bos@mailrank.com>
-maintainer:     Bryan O'Sullivan <bos@mailrank.com>
+author:         Bryan O'Sullivan <bos@serpentine.com>
+maintainer:     Bryan O'Sullivan <bos@serpentine.com>
 stability:      experimental
 tested-with:    GHC == 7.0.3
 synopsis:       Fast conversion between double precision floating point and text
@@ -46,7 +46,6 @@
     double-conversion/test/cctest/*.h
     double-conversion/test/cctest/SConscript
     include/*.h
-    tests/*.cabal
     tests/*.hs
 
 flag developer
@@ -100,9 +99,22 @@
   if impl(ghc >= 6.9) && impl(ghc < 6.11)
     build-depends: integer >= 0.1 && < 0.2
 
+test-suite tests
+  type: exitcode-stdio-1.0
+  hs-source-dirs: tests
+  main-is: Properties.hs
+  ghc-options: -Wall
+  build-depends:
+    base,
+    bytestring,
+    double-conversion,
+    test-framework,
+    test-framework-quickcheck2,
+    text
+
 source-repository head
   type:     git
-  location: https://github.com/mailrank/double-conversion
+  location: https://github.com/bos/double-conversion
 
 source-repository head
   type:     mercurial
diff --git a/double-conversion/src/fast-dtoa.cc b/double-conversion/src/fast-dtoa.cc
--- a/double-conversion/src/fast-dtoa.cc
+++ b/double-conversion/src/fast-dtoa.cc
@@ -31,6 +31,8 @@
 #include "diy-fp.h"
 #include "double.h"
 
+#include <stdio.h>
+
 namespace double_conversion {
 
 // The minimal and maximal target exponent define the range of w's binary
@@ -222,121 +224,42 @@
   return false;
 }
 
-
-static const uint32_t kTen4 = 10000;
-static const uint32_t kTen5 = 100000;
-static const uint32_t kTen6 = 1000000;
-static const uint32_t kTen7 = 10000000;
-static const uint32_t kTen8 = 100000000;
-static const uint32_t kTen9 = 1000000000;
-
 // Returns the biggest power of ten that is less than or equal to the given
 // number. We furthermore receive the maximum number of bits 'number' has.
-// If number_bits == 0 then 0^-1 is returned
+//
+// Returns power == 10^(exponent_plus_one-1) such that
+//    power <= number < power * 10.
+// If number_bits == 0 then 0^(0-1) is returned.
 // The number of bits must be <= 32.
 // Precondition: number < (1 << (number_bits + 1)).
+
+// Inspired by the method for finding an integer log base 10 from here:
+// http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog10
+static unsigned int const kSmallPowersOfTen[] =
+    {0, 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000,
+     1000000000};
+
 static void BiggestPowerTen(uint32_t number,
                             int number_bits,
                             uint32_t* power,
-                            int* exponent) {
+                            int* exponent_plus_one) {
   ASSERT(number < (1 << (number_bits + 1)));
-
-  switch (number_bits) {
-    case 32:
-    case 31:
-    case 30:
-      if (kTen9 <= number) {
-        *power = kTen9;
-        *exponent = 9;
-        break;
-      }  // else fallthrough
-    case 29:
-    case 28:
-    case 27:
-      if (kTen8 <= number) {
-        *power = kTen8;
-        *exponent = 8;
-        break;
-      }  // else fallthrough
-    case 26:
-    case 25:
-    case 24:
-      if (kTen7 <= number) {
-        *power = kTen7;
-        *exponent = 7;
-        break;
-      }  // else fallthrough
-    case 23:
-    case 22:
-    case 21:
-    case 20:
-      if (kTen6 <= number) {
-        *power = kTen6;
-        *exponent = 6;
-        break;
-      }  // else fallthrough
-    case 19:
-    case 18:
-    case 17:
-      if (kTen5 <= number) {
-        *power = kTen5;
-        *exponent = 5;
-        break;
-      }  // else fallthrough
-    case 16:
-    case 15:
-    case 14:
-      if (kTen4 <= number) {
-        *power = kTen4;
-        *exponent = 4;
-        break;
-      }  // else fallthrough
-    case 13:
-    case 12:
-    case 11:
-    case 10:
-      if (1000 <= number) {
-        *power = 1000;
-        *exponent = 3;
-        break;
-      }  // else fallthrough
-    case 9:
-    case 8:
-    case 7:
-      if (100 <= number) {
-        *power = 100;
-        *exponent = 2;
-        break;
-      }  // else fallthrough
-    case 6:
-    case 5:
-    case 4:
-      if (10 <= number) {
-        *power = 10;
-        *exponent = 1;
-        break;
-      }  // else fallthrough
-    case 3:
-    case 2:
-    case 1:
-      if (1 <= number) {
-        *power = 1;
-        *exponent = 0;
-        break;
-      }  // else fallthrough
-    case 0:
-      *power = 0;
-      *exponent = -1;
-      break;
-    default:
-      // Following assignments are here to silence compiler warnings.
-      *power = 0;
-      *exponent = 0;
-      UNREACHABLE();
+  // 1233/4096 is approximately 1/lg(10).
+  int exponent_plus_one_guess = ((number_bits + 1) * 1233 >> 12);
+  // We increment to skip over the first entry in the kPowersOf10 table.
+  // Note: kPowersOf10[i] == 10^(i-1).
+  exponent_plus_one_guess++;
+  // We don't have any guarantees that 2^number_bits <= number.
+  // TODO(floitsch): can we change the 'while' into an 'if'? We definitely see
+  // number < (2^number_bits - 1), but I haven't encountered
+  // number < (2^number_bits - 2) yet.
+  while (number < kSmallPowersOfTen[exponent_plus_one_guess]) {
+    exponent_plus_one_guess--;
   }
+  *power = kSmallPowersOfTen[exponent_plus_one_guess];
+  *exponent_plus_one = exponent_plus_one_guess;
 }
 
-
 // Generates the digits of input number w.
 // w is a floating-point number (DiyFp), consisting of a significand and an
 // exponent. Its exponent is bounded by kMinimalTargetExponent and
@@ -418,10 +341,10 @@
   // Modulo by one is an and.
   uint64_t fractionals = too_high.f() & (one.f() - 1);
   uint32_t divisor;
-  int divisor_exponent;
+  int divisor_exponent_plus_one;
   BiggestPowerTen(integrals, DiyFp::kSignificandSize - (-one.e()),
-                  &divisor, &divisor_exponent);
-  *kappa = divisor_exponent + 1;
+                  &divisor, &divisor_exponent_plus_one);
+  *kappa = divisor_exponent_plus_one;
   *length = 0;
   // Loop invariant: buffer = too_high / 10^kappa  (integer division)
   // The invariant holds for the first iteration: kappa has been initialized
@@ -526,10 +449,10 @@
   // Modulo by one is an and.
   uint64_t fractionals = w.f() & (one.f() - 1);
   uint32_t divisor;
-  int divisor_exponent;
+  int divisor_exponent_plus_one;
   BiggestPowerTen(integrals, DiyFp::kSignificandSize - (-one.e()),
-                  &divisor, &divisor_exponent);
-  *kappa = divisor_exponent + 1;
+                  &divisor, &divisor_exponent_plus_one);
+  *kappa = divisor_exponent_plus_one;
   *length = 0;
 
   // Loop invariant: buffer = w / 10^kappa  (integer division)
diff --git a/tests/Properties.hs b/tests/Properties.hs
--- a/tests/Properties.hs
+++ b/tests/Properties.hs
@@ -1,11 +1,19 @@
-import Data.Double.Conversion
-import Test.QuickCheck
-import Test.Framework (defaultMain, testGroup)
+import Test.Framework (defaultMain)
 import Test.Framework.Providers.QuickCheck2 (testProperty)
+import qualified Data.ByteString.Char8 as B
+import qualified Data.Double.Conversion.ByteString as B
+import qualified Data.Double.Conversion.Text as T
 import qualified Data.Text as T
 
-shortest a = (read . T.unpack . toShortest) a == a
+shortest :: (Double -> String) -> Double -> Double -> Bool
+shortest f a b = case read (f ab) of
+                   ba | isNaN ba      -> isNaN ab
+                      | isInfinite ba -> isInfinite ab && signum ba == signum ab
+                      | otherwise     -> ba == ab
+  where ab = a / b
 
+main :: IO ()
 main = defaultMain [
-        testProperty "shortest" shortest
+         testProperty "b_shortest" $ shortest (B.unpack . B.toShortest)
+       , testProperty "t_shortest" $ shortest (T.unpack . T.toShortest)
        ]
diff --git a/tests/double-conversion-tests.cabal b/tests/double-conversion-tests.cabal
deleted file mode 100644
--- a/tests/double-conversion-tests.cabal
+++ /dev/null
@@ -1,15 +0,0 @@
-name:           double-conversion-tests
-version:        0
-cabal-version:  >= 1.8
-build-type:     Simple
-
-executable qc
-  main-is: Properties.hs
-
-  build-depends:
-    QuickCheck,
-    base,
-    double-conversion,
-    test-framework,
-    test-framework-quickcheck2,
-    text >= 0.11.0.8
