我试图定义一个函数,帮助我模拟使用8位数时的基本操作。
我很难搞清楚这一点。我试图保持尽可能简单而不导入任何内容,所以我开始使用两个包含8个元素的列表(它们是0& #39; s和1' s。
如果我没弄错,它应该从这样开始:
bitsum :: [Int] -> [Int] -> [Int]
bitsum [][] = []
在最后一行之后,它开始变得棘手,因为我无法将列表中的元素添加到一个。
bitsum (x:xs)(y:ys)
我现在所拥有的一切,我认为是正确的。
我的想法是尝试这样的事情:
bitsum :: [Int] -> [Int] -> [Int]
bitsum [][] = []
bitsum (x:xs)[] = (x:xs)
bitsum [](y:ys) = (y:ys)
bitsum (x:xs)(y:ys) | (x:xs) == (y:ys) && < 0 = (x:xs)
| (x:xs) == (y:ys) && > 0 =
但是我觉得我在某个地方转了个弯。
如果有人能帮我解决这个问题,我真的很感激。
答案 0 :(得分:2)
你需要一个进位。您无法逐列添加。让我们一块一块地做:
bitsum :: [Int] -> [Int] -> [Int]
bitsum = bitsum' 0
where
bitsum' _ [] [] = []
这是一个开始。我们从没有进位开始,我们处理不再需要添加的位的情况。那么如果两个位都为0会怎么样?
bitsum' 0 (0:xs) (0:ys) = 0 : bitsum' 0 xs ys
bitsum' 1 (0:xs) (0:ys) = 1 : bitsum' 0 xs ys
好的,所以如果两者都是0,并且进位是0,那么该位的结果是0并且没有进位。如果有携带使用它,并继续没有。
bitsum' 0 (1:xs) (1:ys) = 0 : bitsum' 1 xs ys
bitsum' 1 (1:xs) (1:ys) = 1 : bitsum' 1 xs ys
如果他们是一个,那就相似了。除了总会有一个随身携带。然后,如果他们不同:
bitsum' 0 (x:xs) (y:ys) = 1 : bitsum' 0 xs ys
bitsum' 1 (x:xs) (y:ys) = 0 : bitsum' 1 xs ys
他们必须是0和1,因为我们处理了所有其他情况,因此他们必须加起来一个。你可以弄清楚它应该是什么。你开始看到上面的一些模式,所以这一切都可以缩小,最终得到更短的答案。
bitsum :: [Int] -> [Int] -> [Int]
bitsum = bitsum' 0
where
bitsum' _ [] [] = []
bitsum' carry (x:xs) (y:ys) | x == y = carry : bitsum' x xs ys
| otherwise = (1 - carry) : bitsum' carry xs ys
(1-carry)是一种翻转1到0的奇特方式,反之亦然,因为在这种情况下,该位总是与进位相反。
答案 1 :(得分:2)
这是不必要的。注意按位二进制加法的两个属性:高位由AND给出,低位由XOR给出。这些是:
xor a b = if a == b then 0 else 1
and' 1 1 = 1 -- `and` is a function in Prelude.
and' _ _ = 0
要找到二进制和,只需按位xor和和分别找到低位和高位。移动高位数(左或右,取决于Endian-ness)并取总和,以及低位数。
Little endian:
bitsum0 :: [Int] -> [Int] -> [Int]
bitsum0 xs ys
| (sum xs) == 0 = ys
| (sum ys) == 0 = xs
| otherwise = bitsum0 low (0:high)
where low = zipWith xor xs ys
high = zipWith and' xs ys
Big endian:
bitsum1 :: [Int] -> [Int] -> [Int]
bitsum1 xs ys
| (sum xs) == 0 = ys
| (sum ys) == 0 = xs
| otherwise = bitsum1 low ((tail high) ++ [0])
where low = zipWith xor xs ys
high = zipWith and' xs ys
每个功能中的两名警卫确保终止;最终,递归将最终添加x + 0,这是我们完成的时候。
请注意,没有进行错误检查。溢出和不同长度的列表(以及空列表)是未定义的行为。你的列表可能被填满无意义的垃圾(特别是,and'
将0视为0,其他一切视为1)。也许使用像
data Bit = Bool
type Word_8 = (Bit , Bit , Bit , Bit , Bit , Bit , Bit , Bit )
或更好
import Data.Word
binsum :: Word8 -> Word8 -> Word8
binsum = (+)
答案 2 :(得分:0)
这是Haskell中的一个超级简单的门表示。 刚开始学习Haskell,所以格式很简单,我学习的方式...... 由于在数学中建立一点模拟似乎很有趣,我一起攻击这个..希望它能帮助某人:)
andGate x y = [z | z <- [if (x == 1 && y == 1) then 1 else 0]]
orGate x y = [z | z <- [if (x == 1 || y == 1) then 1 else 0]]
nandGate x y = [z | q <- (andGate x y), z <- [if (q == 0) then 1 else 0 ]]
norGate x y = [z | q <- (orGate x y), z <- [if (q == 0) then 1 else 0 ]]
xorGate x y = [z |
xn <- [if (x == 0) then 1 else 0],
yn <- [if (y == 0) then 1 else 0],
q <- (andGate xn y),
p <- (andGate x yn),
z <- (orGate q p)]
xnorGate x y = [z |
xn <- [if (x == 0) then 1 else 0],
yn <- [if (y == 0) then 1 else 0],
q <- (andGate xn yn),
p <- (andGate x y),
z <- (orGate q p)]
halfAdder a b = [ (x, y) | x <- (xorGate a b), y <- (andGate a b)]
fullAdder a b c = [ (sum, cout) |
u1 <- xorGate a b,
u2 <- andGate a b,
sum <- xorGate u1 c,
u4 <- andGate u1 c,
cout <- orGate u4 u2]