在Haskell中从十进制转换为否定,反之亦然

时间:2014-02-05 09:57:54

标签: haskell functional-programming numbers base

最近我开始在Haskell中在十进制和negabinary之间编写转换函数。我试着用尽可能多的功能来编写它们,也是为了简洁。在下面的答案中,我展示了我对任务的看法。我对您采用的方法的改进或任何评论感兴趣。

2 个答案:

答案 0 :(得分:1)

这是我的努力:

type NegaBinary = [Int]

toInt :: NegaBinary -> Int
toInt = foldl' (\ y x -> x + y*(-2)) 0

fromInt :: Int -> NegaBinary
fromInt = reverse . unfoldr (\ x -> if x == 0 then Nothing else Just (let (d,m) = x `divMod` (-2) in (m,d)))

遗憾的是divMod以错误的方式回答答案;否则这会有点短暂。

答案 1 :(得分:0)

以下是我来回转换的两个功能:

type NegaBinary = String

dec2negbin :: Int -> NegaBinary
dec2negbin = reverse .
             map intToDigit .
                 unfoldr (\x -> if x==0 then Nothing else Just(abs(xrem x (-2)), xdiv x (-2)))
    where
      xrem a b = if b > 0 then rem a b else (-(rem a (-b)))
      xdiv a b = if b > 0 then div a b else (-(div a (-b)))

negbin2dec :: NegaBinary -> Int
negbin2dec = sum . map (\x -> (snd x)*(-2)^(fst x)) . zip [0..] . reverse . map digitToInt

为了清楚起见,我定义了NegaBinary类型。 dec2negbin使用unfoldr函数进行连续分割和余数计算。我还使用了两个本地函数:xremxdiv,因为标准函数(remdiv)具有从下面始终接近被除数的不良行为(意味着在div a b => c b*c中始终低于a)。我想要的是它从方向接近零,所以正面和负面红利的行为是不同的。我知道dec2negbin的定义有点笨重,所以欢迎改进。