[英]Convert Int or Integer to [Word8] or [Bit]
有沒有一種有效的方法將Int
(最好是Integer
)轉換為Word8
列表甚至是位列表? {G,H}為Int -> [Word8]
沒有產生任何有希望的結果......
Int
和Integer
都是Bits
類型類的實例,因此您可以使用該類的函數隨意提取單個位。
由於Int
也是Storable
的實例,因此您可以使用sizeOf
獲取其大小。 因此,對Int
和其他類型的Bits
和Storable
實例的(低效)實現是:
import Foreign.Storable
import Data.Bits
bitList :: (Storable a, Bits a) => a -> [Bool]
bitList x = map (testBit x) [0..8*(sizeOf x)-1]
這給出了例如
bitList (0 :: Int) == [False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False]
bitList (-1 :: Int) == [True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True]
bitList (16 :: Word8) == [False,False,False,False,True,False,False,False]
bitList (maxBound ::Word32) == [True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True]
以下是適用於從谷物包裝內臟撕下的Integer
功能:
--
-- Fold and unfold an Integer to and from a list of its bytes
--
unroll :: Integer -> [Word8]
unroll = unfoldr step
where
step 0 = Nothing
step i = Just (fromIntegral i, i `shiftR` 8)
roll :: [Word8] -> Integer
roll = foldr unstep 0
where
unstep b a = a `shiftL` 8 .|. fromIntegral b
@gspr建議的另一種方法,但不需要Storable
(它支持Integer
s作為獎勵!):
import Data.Bits
bitList :: Bits a => a -> [Bool]
bitList x =
[ testBit x i
| i <- maybe [0..] (enumFromTo 0 . subtract 1) (bitSizeMaybe x)
]
它正確地猜測了整數和單詞的大小,但要注意它會為Integer
提供無限數量的位。
我通過轉換它來擴展@ max-taldykin以顯示從右到左的位,類似於通常顯示位的方式。
import Data.Bits (FiniteBits, finiteBitSize, testBit)
import Data.Int (Int32)
bitList :: FiniteBits a => a -> [Bool]
bitList x = let size = finiteBitSize x
in [testBit x i | i <- enumFromThenTo size (size - 1) 0]
bitListToNum :: Num b => [Bool] -> [b]
bitListToNum = map (\b -> case b of { True -> 1; False -> 0 })
main = do
let listOfBits = bitList (65 :: Int32)
print $ bitListToNum listOfBits
還提供了將其轉換為數字的功能。
在此更新: https : //gist.github.com/a7f3ba5976accc113736f3b22929dddc
您可以使用Data.Vector.Storable和unsafeCast
將其轉換為另一種int類型,然后通過索引將它們拉出來。
let w32 = 800 :: Int32
vec = singleton w32
vec' = unsafeCase vec :: Vector Word8
in toList vec'
或類似於Ptr和東西的東西。
注意:因為它表明這是一個不安全的操作,所以盡可能多地驗證數據。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.