2013-04-05 47 views
3

假設我有很多值得關注的類型爲Word8,Word16Word32。我想擴大它們,將一些解釋爲已簽名,一些解碼爲未簽名,以便我可以將它們全部存儲在[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

是否存在'convert8 True = negate的問題。 fromIntegral'? – 2013-04-05 03:14:50

+0

嗯,是的,因爲我不想否定 - 我想將無符號整數解釋爲signed,這意味着例如'convert8 True 1 == 1'。 – 2013-04-05 03:43:21

+0

但我認爲'convert True'意味着你想要一個負值...這樣一個令人困惑的設計!如果布爾值爲「真」,且所需值爲負值,那麼當使用帶符號的類型(即帶符號類型的正值超出範圍)時,該字爲負值? – 2013-04-05 04:02:27

回答

3

從我記得,GHC將所有整數存儲爲一個機器字。 (換句話說,一個32位的GHC將整數存儲爲32位,一個64位的GHC將它們存儲爲64位)。因此,如果你請求一個8位整數,它將它存儲爲32位,但只有使用前8位是。因此,我相當確定使用fromIntegral的擴展或縮小在運行時實際上是不可用的;它所做的只是更改類型簽名,而沒有運行時成本。 (從無符號轉換爲有符號可能會做符號擴展,但是我不完全確定那個部分是如何工作的,但它可能仍然是一個機器指令)。最好的方法來做到這一點。您可以自己手動實施符號擴展,但執行此操作的內置機器指令可能會更快。

相關問題