【问题标题】:Conversion from decimal to negabinary and vice versa in Haskell [closed]Haskell中从十进制到负数的转换,反之亦然[关闭]
【发布时间】:2014-02-05 09:57:53
【问题描述】:

最近我开始在 Haskell 中编写十进制和negabinary 之间的转换函数。我试图以尽可能多的功能风格来编写它们,同时也是为了简洁。在下面的答案中,我提出了我对这项任务的看法。我会对您对我采用的方法或任何 cmets 的改进感兴趣。

【问题讨论】:

  • 在 Code Review Stack Exchange 上可能会更好?
  • 属于 codereview.stackexchange
  • 不,他确实问了一个问题,只是没有像一个问题那样措辞。问题是,我如何在 Haskell 中计算负数?他也可以将解决方案放在 RosettaCode 上,但问题部分是真实的。我确实有这个问题,这是最好的搜索结果并回答了这个问题。

标签: haskell functional-programming numbers base


【解决方案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 以错误的方式返回答案;否则这会更短一些。

【讨论】:

  • 好吧,我测试了你的函数,而 toInt 工作正常,fromInt 返回错误的结果 - 而且,你的数字中有 -1s。这是编辑后的输出:fromInt 15 => [-1,-1,0,0,0,-1]toInt [1,0,0,1,1] => 15
  • 你是对的。也许有一些方法可以调整它以修复结果......
  • 也许解决方法是我必须对remdiv 进行ugly 修改;)
【解决方案2】:

下面是我来回转换的两个函数:

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 => cb*c 是总是低于a)。我想要的是它向 零的方向接近,因此正股息和负股息的行为是不同的。我知道dec2negbin 的定义有点庞大,欢迎改进。

【讨论】:

    猜你喜欢
    • 2014-09-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-02
    • 2012-08-21
    • 2012-09-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多