Haskell 加宽时将无符号整数解释为有符号整数
假设我有很多Haskell 加宽时将无符号整数解释为有符号整数,haskell,integer,Haskell,Integer,假设我有很多Word8、Word16和Word32类型的值。我想扩展它们,将一些解释为有符号,一些解释为无符号,这样我就可以将它们全部存储在[Int64]中。我知道我可以编写如下函数,其中第一个参数指定是否要将Word8解释为有符号: convert8 :: Bool -> Word8 -> Int64 convert8 False i = fromIntegral i convert8 True i = fromIntegral (fromIntegral i :: Int8)
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
不过,积分的双重
对我来说并不雅观。有没有更好的方法说“把这个字解释成一个有符号的整数,然后把它放在一个更大的Int
”?据我回忆,GHC将所有整数存储为一个机器字。(换句话说,32位GHC将整数存储为32位。64位GHC将整数存储为64位。)因此,如果请求8位整数,它仍将其存储为32位,但仅使用前8位
正因为如此,我相当确定使用fromIntegral
进行加宽或缩小在运行时实际上是不可行的;它所做的只是更改类型签名,而不需要运行时开销。(不过,从无符号转换为有符号可能需要进行符号扩展。我不完全确定这部分是如何工作的。不过,这可能还是一条机器指令。)
简言之,我认为双from integral
可能是最好的方法。您可以自己手动实现符号扩展,但用于实现符号扩展的内置机器指令可能会更快。convert8 True=negate是否有问题。fromIntegral
?是的,因为我不需要求反-我希望无符号整数被解释为有符号的,这意味着,例如,convert8 True 1==1
。但是我认为convert True
意味着你需要一个负值。。。如此令人困惑的设计!如果布尔值为True
,那么您需要的是负值,如果使用有符号类型时单词为负值,那么该值将为负值(即,超出有符号类型的正值的范围)?如果问题不清楚,那么很抱歉问题是Data.Binary.Get
为我提供类型为WordN
的值,我知道(从我的格式规范)其中一些应该被解释为已签名。