在扩展时将无符号整数解释为已签名

时间:2013-04-05 00:03:12

标签: haskell integer

假设我有很多类型为Word8Word16Word32的值。我想扩大它们,将一些解释为已签名,一些解释为无符号,以便我可以将它们全部存储在[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”中?

1 个答案:

答案 0 :(得分:4)

据我所知,GHC将所有整数存储为一个机器字。 (换句话说,32位GHC将整数存储为32位.64位GHC将它们存储为64位。)因此,如果您请求一个8位整数,它仍然存储为32位,但只有使用前8位。

因此,我很确定在运行时使用fromIntegral进行扩展或缩小实际上是无操作;它所做的只是更改类型签名,没有运行时成本。 (然而,从unsigned转换为signed可能正在进行符号扩展。我不完全确定该部分是如何工作的。虽然它可能仍然是一个机器指令。)

简而言之,我认为双fromIntegral可能是最好的方法。您可以自己手动实现符号扩展,但内置的机器指令可能会更快。