Haskell:将Double转换为Int

LeO*_*LeO 1 haskell type-conversion

我想从固定基数计算"我必须使用的数字的哪个幂",例如2.

我想找到一个数字的下一个(整数)幂,例如2 ^ 3 = 8 ==> get2Power 8 ==> 3.

这很简单,但 get2Power 10 ==> 4 由于2^3=8下限和2^4=16上限我想返回上限,4.

通过简单的数学运算,我知道我可以用一些对数函数来计算功率,即log(x) / log(2)得到一个Double.但我希望有下一个Integer.

我的方法看起来像

get2Power :: Integer -> Integer
get2Power x 
  | x <= 0 = -1
  | otherwise = round (log(x) / log (2))     
Run Code Online (Sandbox Code Playgroud)

失败的原因是类型之间缺少一些转换.错误消息无助于了解我所缺少的内容.

有人可以帮我解决如何将Double结果转换为Integer/int的问题吗?

dsi*_*ign 19

对于登陆此页面的人来说,它的标题是"将Double转换为Int".Haskell Prelude中有三个功能可以帮助:圆形,地板天花板.

这是一个例子:

Prelude> let myFloat = 3.1415 :: Double
Prelude> let y = round myFloat :: Int
Prelude> y
3
Prelude> :type y
y :: Int
Run Code Online (Sandbox Code Playgroud)

  • 和truncate :: Integral b => a - > b (3认同)

jos*_*uan 4

不使用-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
Run Code Online (Sandbox Code Playgroud)

另一方面,输入类型可以与输出类型不同(具有相同的主体代码)

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
Run Code Online (Sandbox Code Playgroud)

注意:由于我们正在使用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!"
Run Code Online (Sandbox Code Playgroud)

最后,如果您正在使用位,则可以使用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
Run Code Online (Sandbox Code Playgroud)

  • 虽然“也许”当然是一件值得了解的好事情并且在这里相当合理,但我不会说你_必须_使用它。对于有效范围很明显的数学函数,通常认为可以将它们保留为部分函数(至少在编写 Haskell 标准模块时是这样)。当然,“-1”不是可接受的错误情况,但抛出异常是可以的。 (2认同)