Преобразование строки, представляющей двоичное число, в базу 10 строк haskell У меня есть строка "1001", и мне нужна строка "9". В числовой библиотеке есть (довольно неуклюжая) showIntAtBase, но мне не удалось найти обратное. Ответ 1 Вот более или менее то, что вы искали от Prelude. Из Numeric: (NB: readInt является "двойным" из showIntAtBase, а readDec является "двойным" из showInt. Непоследовательное именование - это исторический случай.) 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 Ответ 2 Прошло некоторое время с момента публикации, но для будущих читателей я бы использовал следующее: import Data.Char (digitToInt) import Data.List (foldl') toDec :: String -> Int toDec = foldl' (\acc x -> acc * 2 + digitToInt x) 0 Не нужно замедлять работу, используя ^, reverse, zipWith, length и т.д. Кроме того, использование строгой фальшивки снижает требования к памяти. Ответ 3 Из 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 Ответ 4 Это помогает? http://pleac.sourceforge.net/pleac_haskell/numbers.html со страницы: 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 Ответ 5 Поскольку 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│ └───┴───┴───┴───┘ так очевидно: fromBinary :: String -> Int fromBinary str = sum $ zipWith toDec (reverse str) [0 .. length str] where toDec a b = digitToInt a * (2 ^ b) Ответ 6 binario :: Int -> [Int] binario 1 = [1] binario n = binario(div x 2)++(mod n 2:[]) кредиты @laionzera
Ответ 1 Вот более или менее то, что вы искали от Prelude. Из Numeric: (NB: readInt является "двойным" из showIntAtBase, а readDec является "двойным" из showInt. Непоследовательное именование - это исторический случай.) 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
Ответ 2 Прошло некоторое время с момента публикации, но для будущих читателей я бы использовал следующее: import Data.Char (digitToInt) import Data.List (foldl') toDec :: String -> Int toDec = foldl' (\acc x -> acc * 2 + digitToInt x) 0 Не нужно замедлять работу, используя ^, reverse, zipWith, length и т.д. Кроме того, использование строгой фальшивки снижает требования к памяти.
Ответ 3 Из 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
Ответ 4 Это помогает? http://pleac.sourceforge.net/pleac_haskell/numbers.html со страницы: 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
Ответ 5 Поскольку 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│ └───┴───┴───┴───┘ так очевидно: fromBinary :: String -> Int fromBinary str = sum $ zipWith toDec (reverse str) [0 .. length str] where toDec a b = digitToInt a * (2 ^ b)
Ответ 6 binario :: Int -> [Int] binario 1 = [1] binario n = binario(div x 2)++(mod n 2:[]) кредиты @laionzera