Haskell: Convert Double to Int
haskell, type-conversion
Solution
Not use `-1` (you can but) use `Maybe` (or throw exception if you don't want control i.e. is controlled in other way)
get2Power :: Integral a => a -> Maybe a
get2Power x | x <= 0 = Nothing
| otherwise = Just (ceiling (log (fromIntegral x) / log 2))
Prelude> get2Power (256 :: Int)
Just 8
it :: Maybe Integer
on the other hand, input type can be different than output type (with the same body code)
get2Power :: (Integral a, Integral b) => a -> Maybe b
^^^^^^^^^^^^^^^^^^^^^^
(note how to force args to be Integral: Int, Integer, ...)
get2Power x | x <= 0 = Nothing
| otherwise = Just (ceiling (log (fromIntegral x) / log 2))
Prelude> get2Power (2^123 :: Integer) :: Maybe Int
^^^^^^^^^^^ ^^^
(note here how to force certain type)
Just 123
it :: Maybe Int
Note: since we are using `Maybe` (to avoid a bad `-1` response) you must control flow control in your code like
main = do
putStrLn "Enter a number:"
n <- readLn
case get2Power n of
Just k -> putStrLn $ "2^" ++ show k ++ " is above " ++ show n
Nothing -> putStrLn "Negative numbers not allowed!"
finally, if you are working with bits, you can get used bits to store certain number using Data.Bits
usedBits :: Bits a => a -> Int
usedBits n = length $ dropWhile not bs
where bs = [testBit n b | b <- reverse [0..bitSize n - 1]]
Prelude Data.Bits> usedBits (256 :: Int)
9
it :: Int
Problem
I want to compute "which power of a number do I have to use" from a fixed base, e.g. 2. I want to find the next (integer) power of a number, e.g. `2 ^ 3 = 8 ==> get2Power 8 ==> 3`. This is simple, but `get2Power 10 ==> 4` since `2^3=8` as the lower bound and `2^4=16` as the upper bound I want to return the upper one, `4`. With simple math I know that I can calculate the power with some logarithm function, i.e. `log(x) / log(2)` which results in a Double. But I want to have the next `Integer`. My approach looks like ``` get2Power :: Integer -> Integer get2Power x | x <= 0 = -1 | otherwise = round (log(x) / log (2)) ``` which fails cause there is missing some conversion between the Types. The error message is not helpful to get an idea of what I'm missing. Could anybody give me a helping hand about how to transform the Double result into an Integer/int?