将Int或Integer转换为[Word8]或[Bit]

时间:2015-07-03 13:43:10

标签: haskell

是否有一种有效的方法可以将Int(最好是Integer)转换为Word8列表,甚至是列表列表? {G,H} Int -> [Word8]的{​​{1}} oogling没有产生任何有希望的结果......

5 个答案:

答案 0 :(得分:6)

IntInteger都是Bits类型类的实例,因此您可以使用该类的函数随意提取单个位。

由于Int也是Storable的实例,因此您可以使用sizeOf获取其大小。因此,Int以及BitsStorable实例的其他类型的(低效)实现是:

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]

答案 1 :(得分:2)

以下是适用于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 翻录.ui-selectmenu-menu .ui-menu {max-height: 200px;} 的功能:

{{1}}

答案 2 :(得分:2)

@gspr建议的另一种方法,但不需要Storable(它支持Integer作为奖励!):

import Data.Bits

bitList :: Bits a => a -> [Bool]
bitList x =
    [ testBit x i
    | i <- maybe [0..] (enumFromTo 0 . subtract 1) (bitSizeMaybe x)
    ]

它正确地猜测了整数和单词的大小,但要注意它会为Integer提供无限多的位。

答案 3 :(得分:0)

我通过转换它来扩展@ 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

答案 4 :(得分:0)

您可以使用Meaning of "this" in node.js modules and functionsunsafeCast将其转换为另一种int类型,然后通过索引将它们拉出来。

let w32 = 800 :: Int32
    vec = singleton w32
    vec' = unsafeCase vec :: Vector Word8
in toList vec'

或与Data.Vector.Storable类似的东西。

注意:,因为它表明这是一个不安全的操作,因此请尽可能多地验证数据。