Non-decimal radices/Convert: Difference between revisions
Content added Content deleted
(→{{header|Haskell}}: Deriving toBase :: Int -> Int -> String from inBaseDigits :: [Char] -> Int -> String) |
|||
Line 1,227: | Line 1,227: | ||
Using built-in functions to convert integer into string, and vice versa, at any base up to 16: |
Using built-in functions to convert integer into string, and vice versa, at any base up to 16: |
||
<lang haskell>Prelude> Numeric.showIntAtBase 16 Char.intToDigit 42 "" |
|||
"2a" |
|||
Prelude> fst $ head $ Numeric.readInt 16 Char.isHexDigit Char.digitToInt "2a" |
|||
42</lang> |
|||
It's actually more useful to represent digits internally as numbers instead of characters, because then one can define operations that work directly on this representation. |
|||
So conversion to and from digits represented as 0-9 and a-z is done in an additional step. |
|||
<lang haskell>import Data.List |
|||
import Data.Char |
|||
toBase :: Int -> Int -> [Int] |
|||
toBase b v = toBase' [] v where |
|||
toBase' a 0 = a |
|||
toBase' a v = toBase' (r:a) q where (q,r) = v `divMod` b |
|||
fromBase :: Int -> [Int] -> Int |
|||
fromBase b ds = foldl' (\n k -> n * b + k) 0 ds |
|||
toAlphaDigits :: [Int] -> String |
|||
toAlphaDigits = map convert where |
|||
convert n | n < 10 = chr (n + ord '0') |
|||
| otherwise = chr (n + ord 'a' - 10) |
|||
fromAlphaDigits :: String -> [Int] |
|||
fromAlphaDigits = map convert where |
|||
convert c | isDigit c = ord c - ord '0' |
|||
| isUpper c = ord c - ord 'A' + 10 |
|||
| isLower c = ord c - ord 'a' + 10</lang> |
|||
Example: |
|||
<lang haskell>*Main> toAlphaDigits $ toBase 16 $ 42 |
|||
"2a" |
|||
*Main> fromBase 16 $ fromAlphaDigits $ "2a" |
|||
42</lang> |
|||
Or, allow for digit variants like upper case vs lower case Hexadecimal, we can express our conversion function(s) in terms of a more general '''inBaseDigits''' function which, given an ordered list of digits as its first argument, returns an Int -> String unfold function. (The base is the length of the digit list). |
|||
If we want to assume a default character set, then a general '''toBase''' (Int -> Int -> String) can be also be derived from '''inBaseDigits'''. |
|||
<lang haskell>import Data.List (unfoldr) |
<lang haskell>import Data.List (unfoldr) |
||
Line 1,280: | Line 1,237: | ||
else [] |
else [] |
||
inBaseDigits :: |
inBaseDigits :: String -> Int -> String |
||
inBaseDigits ds n = |
inBaseDigits ds n = |
||
let base = length ds |
let base = length ds |
||
Line 1,314: | Line 1,271: | ||
11111110 |
11111110 |
||
376 |
376 |
||
fe |
fe |
||
11111110</pre> |
|||
=={{header|HicEst}}== |
=={{header|HicEst}}== |