Convert a string representing a binary number to a base 10 string haskell

前端 未结 6 667
伪装坚强ぢ
伪装坚强ぢ 2021-01-01 18:11

I have the string \"1001\" and I want the string \"9\".

The numeric library has the (rather clunky) showIntAtBase, but I haven\'t been able to find the opposite.

相关标签:
6条回答
  • 2021-01-01 18:23

    Here is more or less what you were looking for from Prelude. From Numeric:

    (NB: readInt is the "dual" of showIntAtBase, and readDec is the "dual" of showInt. The inconsistent naming is a historical accident.)

    import Data.Char  (digitToInt)
    import Data.Maybe (listToMaybe)
    import Numeric    (readInt)
    
    readBin :: Integral a => String -> Maybe a
    readBin = fmap fst . listToMaybe . readInt 2 (`elem` "01") digitToInt
    -- readBin "1001" == Just 9
    
    0 讨论(0)
  • 2021-01-01 18:23

    From PLEAC:

    bin2dec :: String -> Integer
    bin2dec = foldr (\c s -> s * 2 + c) 0 . reverse . map c2i
        where c2i c = if c == '0' then 0 else 1
    
    0 讨论(0)
  • 2021-01-01 18:28

    Because

    1001 = 1 * 2^0 + 0 * 2^1 + 0 * 2^2 + 1 * 2^3 = 1 + 0 + 0 + 8 = 9
    
    ┌───┬───┬───┬───┐
    │1  │0  │0  │1  │
    ├───┼───┼───┼───┤
    │2^3│2^2│2^1│2^0│
    └───┴───┴───┴───┘
    

    so obviously:

    fromBinary :: String -> Int
    fromBinary str = sum $ zipWith toDec (reverse str) [0 .. length str]
      where toDec a b = digitToInt a * (2 ^ b)
    
    0 讨论(0)
  • 2021-01-01 18:47

    This helps? http://pleac.sourceforge.net/pleac_haskell/numbers.html

    from the page:

    bin2dec :: String -> Integer
    bin2dec = foldr (\c s -> s * 2 + c) 0 . reverse . map c2i
        where c2i c = if c == '0' then 0 else 1
    -- bin2dec "0110110" == 54
    
    0 讨论(0)
  • 2021-01-01 18:47
    binario :: Int -> [Int]                      
    binario 1 = [1]                  
    binario n = binario(div x 2)++(mod n 2:[])
    

    credits to @laionzera

    0 讨论(0)
  • 2021-01-01 18:48

    It's been a while since the original post but, for future readers' benefit, I would use the following:

    import Data.Char (digitToInt)
    import Data.List (foldl')
    
    toDec :: String -> Int
    toDec = foldl' (\acc x -> acc * 2 + digitToInt x) 0
    

    No need to slow things down by using ^, reverse, zipWith, length, etc.

    Also, using a strict fold reduces memory requirements.

    0 讨论(0)
提交回复
热议问题