Haskell 将 Word8 转换为 Int 到位
Haskell convert Word8 to Int to Bits
我想将 Word8 转换为 Int,这样我就可以将它转换为位列表,是否可以将其转换为 int 或直接转换为位?
这是我当前的代码片段
intsToBits :: Int -> [Bit]
intsToBits x =
reverse (go x) where
go 0 = [Zero]
go n | n `mod` 2 == 1 = One : go (n `div` 2)
| n `mod` 2 == 0 = Zero : go (n `div` 2)
go _ = []
word8ToInt :: Word8 -> Int
word8ToInt = fromIntegral
decoder :: BS.ByteString -> IO [Bit]
decoder raw =
do
let raw' = BS.unpack raw
let ls = go raw'
return ls
where
go [] = []
go [x] = intsToBits $ x
go (x:xs) = intsToBits (word8ToInt x) ++ go xs
Word8
是 FiniteBits
class 的实例,因此您可以使用类似
toBitList x = map (testBit x) [0..(finiteBitSize x-1)]
或者,如果您想要反过来,[(finiteBitSize x-1), (finiteBitSize x-2)..0]
。
我从您的编辑中看到您(显然)希望您的位按从最高有效位到最低有效位的顺序排列,并且您不想要任何前导零。有多种方法可以做到这一点,但最简单的可能是使用 countLeadingZeros
.
修改上述方法
关于提问的元数据:你真的应该举一些例子来说明你是如何尝试解决问题的。害羞的是,至少有一个你想要的结果的例子,比如 "bits" 对你意味着什么。我倾向于将 Word8
值的集合视为位,因此需要执行操作。
也就是说,让我们提出并回答一系列相关问题。
Haskell中的位运算符是什么?
如果你想要位级操作,而不是像 x || 2^i
这样的算术技巧,你可以使用位 class:
中的函数
Prelude> import Data.Bits
Prelude Data.Bits> :i Bits
class Eq a => Bits a where
(.&.) :: a -> a -> a
(.|.) :: a -> a -> a
xor :: a -> a -> a
complement :: a -> a
shift :: a -> Int -> a
rotate :: a -> Int -> a
zeroBits :: a
bit :: Int -> a
setBit :: a -> Int -> a
clearBit :: a -> Int -> a
complementBit :: a -> Int -> a
testBit :: a -> Int -> Bool
bitSizeMaybe :: a -> Maybe Int
bitSize :: a -> Int
isSigned :: a -> Bool
shiftL :: a -> Int -> a
unsafeShiftL :: a -> Int -> a
shiftR :: a -> Int -> a
unsafeShiftR :: a -> Int -> a
rotateL :: a -> Int -> a
rotateR :: a -> Int -> a
popCount :: a -> Int
还有 FiniteBits
class:
class Bits b => FiniteBits b where
finiteBitSize :: b -> Int
countLeadingZeros :: b -> Int
countTrailingZeros :: b -> Int
如何将 Word8
转换为 [Bool]
?
这只是简单地测试字中的每一位,而b
toBits x = [testBit x i | i <- [0.. finiteBitSize x - 1]
如何将 Word8
转换为我称为 Bit
的数据类型,但我不会向您展示?
在你第一次编辑后,我现在认为你有 data Bit = Zero | One
但不清楚这是否正确。看起来作业和这里给出的建议应该足以完成剩下的任何一种方式。
我想将 Word8 转换为 Int,这样我就可以将它转换为位列表,是否可以将其转换为 int 或直接转换为位?
这是我当前的代码片段
intsToBits :: Int -> [Bit]
intsToBits x =
reverse (go x) where
go 0 = [Zero]
go n | n `mod` 2 == 1 = One : go (n `div` 2)
| n `mod` 2 == 0 = Zero : go (n `div` 2)
go _ = []
word8ToInt :: Word8 -> Int
word8ToInt = fromIntegral
decoder :: BS.ByteString -> IO [Bit]
decoder raw =
do
let raw' = BS.unpack raw
let ls = go raw'
return ls
where
go [] = []
go [x] = intsToBits $ x
go (x:xs) = intsToBits (word8ToInt x) ++ go xs
Word8
是 FiniteBits
class 的实例,因此您可以使用类似
toBitList x = map (testBit x) [0..(finiteBitSize x-1)]
或者,如果您想要反过来,[(finiteBitSize x-1), (finiteBitSize x-2)..0]
。
我从您的编辑中看到您(显然)希望您的位按从最高有效位到最低有效位的顺序排列,并且您不想要任何前导零。有多种方法可以做到这一点,但最简单的可能是使用 countLeadingZeros
.
关于提问的元数据:你真的应该举一些例子来说明你是如何尝试解决问题的。害羞的是,至少有一个你想要的结果的例子,比如 "bits" 对你意味着什么。我倾向于将 Word8
值的集合视为位,因此需要执行操作。
也就是说,让我们提出并回答一系列相关问题。
Haskell中的位运算符是什么?
如果你想要位级操作,而不是像 x || 2^i
这样的算术技巧,你可以使用位 class:
Prelude> import Data.Bits
Prelude Data.Bits> :i Bits
class Eq a => Bits a where
(.&.) :: a -> a -> a
(.|.) :: a -> a -> a
xor :: a -> a -> a
complement :: a -> a
shift :: a -> Int -> a
rotate :: a -> Int -> a
zeroBits :: a
bit :: Int -> a
setBit :: a -> Int -> a
clearBit :: a -> Int -> a
complementBit :: a -> Int -> a
testBit :: a -> Int -> Bool
bitSizeMaybe :: a -> Maybe Int
bitSize :: a -> Int
isSigned :: a -> Bool
shiftL :: a -> Int -> a
unsafeShiftL :: a -> Int -> a
shiftR :: a -> Int -> a
unsafeShiftR :: a -> Int -> a
rotateL :: a -> Int -> a
rotateR :: a -> Int -> a
popCount :: a -> Int
还有 FiniteBits
class:
class Bits b => FiniteBits b where
finiteBitSize :: b -> Int
countLeadingZeros :: b -> Int
countTrailingZeros :: b -> Int
如何将 Word8
转换为 [Bool]
?
这只是简单地测试字中的每一位,而b
toBits x = [testBit x i | i <- [0.. finiteBitSize x - 1]
如何将 Word8
转换为我称为 Bit
的数据类型,但我不会向您展示?
在你第一次编辑后,我现在认为你有 data Bit = Zero | One
但不清楚这是否正确。看起来作业和这里给出的建议应该足以完成剩下的任何一种方式。