on master help sign in
Fix miscounting of digits (gh-99)
commit630e16943da1772afab4122aeabec3556e39b4d0 authorBryan O'Sullivan <bos@serpentine.com> dateThu 6 Nov 2014, 10:10 (12 years ago) parent18dd483
2 files changed+11−35
Data/Text/Lazy/Builder/Int.hs+11−3 tests/Tests/Properties.hs−32
Data/Text/Lazy/Builder/Int.hs+11−3
@@ -1,4 +1,5 @@
1−{-# LANGUAGE BangPatterns, CPP, MagicHash, RankNTypes, UnboxedTuples #-}
1+{-# LANGUAGE BangPatterns, CPP, MagicHash, RankNTypes, ScopedTypeVariables,
2+ UnboxedTuples #-}
23#if __GLASGOW_HASKELL__ >= 702
34{-# LANGUAGE Trustworthy #-}
45#endif
@@ -133,8 +134,15 @@ i2w v = zero + fromIntegral v
133134
134135countDigits :: (Integral a) => a -> Int
135136{-# INLINE countDigits #-}
136−countDigits v0 = go 1 (fromIntegral v0 :: Word64)
137− where go !k v
137+countDigits v0
138+ | fromIntegral v64 == v0 = go 1 v64
139+ | otherwise = goBig 1 (fromIntegral v0)
140+ where v64 = fromIntegral v0
141+ goBig !k (v :: Integer)
142+ | v > big = goBig (k + 19) (v `quot` big)
143+ | otherwise = go k (fromIntegral v)
144+ big = 10000000000000000000
145+ go !k (v :: Word64)
138146 | v < 10 = k
139147 | v < 100 = k + 1
140148 | v < 1000 = k + 2
tests/Tests/Properties.hs−32
@@ -758,36 +758,6 @@ tb_decimal_big_int64 (BigBounded (a::Int64)) = tb_decimal a
758758tb_decimal_big_word (BigBounded (a::Word)) = tb_decimal a
759759tb_decimal_big_word64 (BigBounded (a::Word64)) = tb_decimal a
760760
761−countDigits :: (Integral a) => a -> Int
762−countDigits v0
763− | v0 > max64 = big 20 (v0 `quot` 10000000000000000000)
764− | otherwise = go 1 (fromIntegral v0 :: Word64)
765− where
766− max64 = fromIntegral (maxBound :: Word64)
767− big !k v
768− | v > max64 = big (k+20) (v `quot` 10000000000000000000)
769− | otherwise = go k (fromIntegral v :: Word64)
770− go !k v
771− | v < 10 = k
772− | v < 100 = k + 1
773− | v < 1000 = k + 2
774− | v < 1000000000000 =
775− k + if v < 100000000
776− then if v < 1000000
777− then if v < 10000
778− then 3
779− else 4 + fin v 100000
780− else 6 + fin v 10000000
781− else if v < 10000000000
782− then 8 + fin v 1000000000
783− else 10 + fin v 100000000000
784− | otherwise = go (k + 12) (v `quot` 1000000000000)
785− fin v n = if v >= n then 1 else 0
786−
787−t_cd (Big k) = counterexample (show x ++ " /= " ++ show y) (x == y)
788− where x = countDigits k
789− y = length (show k)
790−
791761tb_hex :: (Integral a, Show a) => a -> Bool
792762tb_hex = (TB.toLazyText . TB.hexadecimal) `eq` (TL.pack . flip showHex "")
793763
@@ -889,8 +859,6 @@ shorten n t@(S.Stream arr off len)
889859tests :: Test
890860tests =
891861 testGroup "Properties" [
892− testProperty "t_cd" t_cd,
893−
894862 testGroup "creation/elimination" [
895863 testProperty "t_pack_unpack" t_pack_unpack,
896864 testProperty "tl_pack_unpack" tl_pack_unpack,