I am trying to calculate the length of an Integer in Haskell, using the fact that the length is equal to truncate (log10(x)+1)
.
Using Integers I created:
len :: Integer -> Integer
len i = toInteger (truncate (logBase 10 (fromIntegral i)) + 1)
Unfortunately, not all numbers get the correct length. I tried a few different cases and found that:
logBase 10 10 = 1.0
logBase 10 100 = 2.0
logBase 10 1000 = 2.9999..6
logBase 10 10000 = 4.0
logBase 10 100000 = 5.0
logBase 10 1000000 = 5.9999999
Is there a reason why logBase 10 1000
doesn't return 3.0? How do I get the correct log-value for 1000 in base 10?
logBase
is defined aslog y / log x
; the division is probably the culprit, as while thelog
will be correct (with regard to roundings), the division of them doesn't have to be. – Osteogenesislog
is not necessary, you could avoid floating point operation with repeatedly divide by 10 (and higher power of 10). – Hittitenumbers
package, and calllogBase 10 1000 :: BigFloat Prec50
, then round that into float or double. Easiest, but not necessarily the best. – OsteogenesisDouble
Floating precision then useFloat
type instead and it seems fine. Such aslogBase 10 (1000 :: Float)
would return3.0
or functionallylogBase 10 . (fromInteger :: Integer -> Float) $ 1000
would do the same. – Layton