2012-04-05 2 views
6

Есть ли функция платформы, которая будет делать следующее?Преобразование номера базы

convertBase :: (Num a, Num b) => Int -> Int -> [a] -> [b] 

Преобразование числа из базы 'a' в базу 'b', где каждый элемент списка является цифрой в числе. , например:

convertBase 2 10 [1,1,0,1] = [1, 3] 

Я надеюсь, что имеет смысл, дайте мне знать, если я могу очистить что-либо до

+0

функцией платформы вы имеете в виду часть стандартных библиотек? – j13r

+0

или даже на хаке –

+0

Зачем различать типы 'a' и' b', разве это не просто 'Интеграл'? –

ответ

13

Используя digits пакет из Hackage:

import Data.Digits (digits, unDigits) 

convertBase :: Integral a => a -> a -> [a] -> [a] 
convertBase from to = digits to . unDigits from 

Вы можете добавить fromIntegral там, если вы необходимо, чтобы типы ввода и вывода были разными. Кроме того, ограничение Integral имеет больше смысла, чем Num, поскольку вы, вероятно, не хотите иметь дело со сложными цифрами или цифрами с плавающей запятой.

+0

Полученная функция принимает список интегралов. Если я создаю 'decToBin = convertBase 10 2', что означает использовать' decToBin [10,10] '? – CMCDragonkai

+0

О, я узнал, что 'decToBin [10, 10]' такой же, как 'decToBin [1010]'. Он просто объединяет все числа в списке. – CMCDragonkai

2

Пара идей:

  • использовать showIntAtBase или Text.printf для преобразования к строке и конвертировать обратно в другую базу
  • напишите сами - проще, когда одно основание всегда кратно другому

Вот ссылка, которая может помочь вам: http://rosettacode.org/wiki/Non-decimal_radices/Convert#Haskell - недесятичных корни/Преобразовать

7

Ближе всего в Haskell платформы от модуля Numeric:

readInt :: Num a => a -> (Char -> Bool) -> (Char -> Int) -> ReadS a showIntAtBase :: Integral a => a -> (Int -> Char) -> a -> ShowS

fromBase :: Int -> String -> Int 
fromBase base = fst . head . readInt base ((<base).digitToInt) digitToInt 

toBase :: Int -> Int -> String 
toBase base num = showIntAtBase base intToDigit num "" 

fromBaseToBase :: Int -> Int -> String -> String 
fromBaseToBase from to = toBase to . fromBase from 
+1

Я хочу добавить, что это работает только до базы 16 – newacct

+0

Что легко растяжимо, если вы предоставляете свою собственную функцию «intToDigit», поддерживающую базы> 16 – Francesquini

Смежные вопросы