Haskell logbase error
If you don't need Double
Floating precision then use Float
type instead and it seems fine. Such as logBase 10 (1000 :: Float)
would return 3.0
or functionally logBase 10 . (fromInteger :: Integer -> Float) $ 1000
would do the same.
As per your code toInteger
seems redundant since truncate :: (Integral b, RealFrac a) => a -> b
already does that job. So may simply do like
len :: Integer -> Integer
len = (+1) . truncate . logBase 10 . (fromIntegral :: Integer -> Float)
This will work correctly up until 9999987.
There is an integer log base function in GHC modules which has type Integer -> Integer -> Int#
.
Example usage:
{-# LANGUAGE MagicHash #-}
import Control.Monad
import GHC.Integer.Logarithms ( integerLogBase# )
import GHC.Exts (Int(..))
main = do
forM_ [(1::Int)..20] $ \n -> do
let a = 10^n-1
la = I# (integerLogBase# 10 a)
b = 10^n
lb = I# (integerLogBase# 10 b)
putStrLn $ show a ++ " -> " ++ show la
putStrLn $ show b ++ " -> " ++ show lb
Output:
9 -> 0
10 -> 1
99 -> 1
100 -> 2
999 -> 2
1000 -> 3
9999 -> 3
10000 -> 4
99999 -> 4
100000 -> 5
999999 -> 5
1000000 -> 6
9999999 -> 6
...
9999999999999999999 -> 18
10000000000000000000 -> 19
99999999999999999999 -> 19
100000000000000000000 -> 20