我想从固定基数计算“我必须使用的数字的哪个幂”,例如2.
我想找到一个数字的下一个(整数)幂,例如2 ^ 3 = 8 ==> get2Power 8 ==> 3
。
这很简单,但get2Power 10 ==> 4
因为2^3=8
作为下限而2^4=16
作为上限我想返回上限4
。
通过简单的数学运算,我知道我可以用一些对数函数来计算功率,即log(x) / log(2)
,这会产生一个双精度。但我想拥有下一个Integer
。
我的方法看起来像
get2Power :: Integer -> Integer
get2Power x
| x <= 0 = -1
| otherwise = round (log(x) / log (2))
失败导致类型之间缺少某些转换。错误消息无助于了解我所缺少的内容。
有人可以帮我解决如何将Double结果转换为Integer / int的问题吗?
答案 0 :(得分:16)
对于登陆此页面的人来说,其标题是“将Double转换为Int”。 Haskell Prelude中有三个函数可以提供帮助:round,floor和ceiling。
以下是一个例子:
Prelude> let myFloat = 3.1415 :: Double
Prelude> let y = round myFloat :: Int
Prelude> y
3
Prelude> :type y
y :: Int
答案 1 :(得分:3)
不使用-1
(你可以但是)使用Maybe
(如果你不想要控制,则抛出异常,即以其他方式控制)
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
另一方面,输入类型可以与输出类型(具有相同的主体代码)不同
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
注意:,因为我们正在使用Maybe
(以避免错误的-1
响应)您必须控制代码中的流量控制,例如
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!"
最后,如果您正在使用位,您可以使用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