假设我有很多类型为Word8
,Word16
和Word32
的值。我想扩大它们,将一些解释为已签名,一些解释为无符号,以便我可以将它们全部存储在[Int64]
中。我知道我可以编写类似下面的函数,其中第一个参数指定我们是否要将Word8
解释为已签名:
convert8 :: Bool -> Word8 -> Int64
convert8 False i = fromIntegral i
convert8 True i = fromIntegral (fromIntegral i :: Int8)
这给了我想要的结果:
*Main> convert8 False 128
128
*Main> convert8 True 128
-128
虽然双fromIntegral
对我来说不够优雅。有没有更好的方式来说“将此Word
解释为有符号整数并将其粘贴在更大的Int
”中?
答案 0 :(得分:4)
据我所知,GHC将所有整数存储为一个机器字。 (换句话说,32位GHC将整数存储为32位.64位GHC将它们存储为64位。)因此,如果您请求一个8位整数,它仍然存储为32位,但只有使用前8位。
因此,我很确定在运行时使用fromIntegral
进行扩展或缩小实际上是无操作;它所做的只是更改类型签名,没有运行时成本。 (然而,从unsigned转换为signed可能正在进行符号扩展。我不完全确定该部分是如何工作的。虽然它可能仍然是一个机器指令。)
简而言之,我认为双fromIntegral
可能是最好的方法。您可以自己手动实现符号扩展,但内置的机器指令可能会更快。