Recently I set about to writing conversion functions in Haskell between decimal and negabinary. I tried to write them in as much functional a style as possible, also aiming at brevity. Below I present my take at the task. I'd be interested in your refinements of the method I employ or any comments whatsoever.
These are my two functions for converting back and forth:
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
I defined the NegaBinary
type just for clarity. The dec2negbin
employs the unfoldr
function for sequential divisions and remainder calculations. I also used two local functions: xrem
and xdiv
, because the standard functions (rem
and div
) had the undesirable behavior of always approaching the dividend from below (meaning that in div a b => c
b*c
is always lower than a
). What I wanted is for it to approach in the direction from zero, so the behavior is different for positive and negative dividends. I know the definition of dec2negbin
is a bit bulky, so improvements are welcome.