4

假设我有很多 type 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”?

4

1 回答 1

4

据我回忆,GHC 将所有整数存储为一个机器字。(换句话说,32 位 GHC 将整数存储为 32 位。64 位 GHC 将它们存储为 64 位。)因此,如果您请求一个 8 位整数,它无论如何都将其存储为 32 位,但仅使用前 8 位。

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

简而言之,我认为双重fromIntegral可能是做到这一点的最佳方式。您可以自己手动实现符号扩展,但执行此操作的内置机器指令可能会更快。

于 2013-04-05T07:49:58.527 回答