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 :: [Char] -> Int -> String
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</pre>
fe
11111110</pre>


=={{header|HicEst}}==
=={{header|HicEst}}==